04 DPF Simple Extensibility
04 DPF Simple Extensibility
Literature (To Be Read)
1 or +
Terminator Recurser
preHandleRequest()
handleRequest() handleRequest() for all g in childObject(s)
preHandleRequest(Component)
Chapter 4 – Extensibility Patterns g.handleRequest()
Software Technology Group / Dr. Sebastian Götz Folie 9
postHandleRequest(Component)
Design Patterns and Frameworks // 30.10.2018 postHandleRequest()
Incentive
:Cons :Cons
:Cons
:Cons :Cons
:Cons
:Nil :Nil
Component *
Client
childObjects
commonOperation()
preHandleRequest(Component)
}
postHandleRequest(Component)
add(Component)
remove(Component)
Pseudo implementations
Leaf Composite
commonOperation() commonOperation() for all g in childObjects
add(Component) g.commonOperation()
remove(Component)
getType(int)
:Picture
Due to the n-recursion, new children can always be added into a composite node
Whenever you have to program an extensible part of a framework, consider
Composite
:Client
A:Decorator
B:Decorator RealObject:
ref ConcreteMimiced
hidden Class
hidden
ConcreteMimicedClass Decorator
mimicedOperation()
mimicedOperation()
preAction()
postAction() preAction();
mimiced.mimicedOperation();
postAction();
ConcreteDecoratorA ConcreteDecoratorB
super.mimicedOperation();
mimicedOperation() mimicedOperation() additionalStuff():
1
Widget
mimiced
draw()
TextWidget WidgetDecorator
draw() draw()
mimiced.draw()
Frame Scrollbar
super.draw();
super.draw(); draw() draw() drawScrollbar():
drawFrame():
1
Record
access() mimiced
TransientRecord PersistentDecorator
access() access()
mimiced.access()
PersistentRead PersistentRecord
OnlyRecord if (!loaded()) load();
access() super.access();
if (!loaded()) load(); access()
boolean loaded() if (modified()) dump():
super.access(); boolean loaded()
boolean modified()
load()
load()
dump()
Library Library
New Features
Decorator with
New Features
Delegate an action to a list of delegatees that attempt to solve the problem one
after the other
They delegate further on, down the chain
No core object
ObjectStructure:
:Client
A:ConcreteWorker
aWorker B:ConcreteWorker
successor ...
successor
Successor
1
Client Worker
Work()
ConcreteWorker1 ConcreteWorker2
Work() Work()
Text:Widget
:PrintButton :OKButton
:PrintDialog :StoreDialog
Dialog Button
nextWorker nextWorker
WorkOnHelpQuery()
showHelp()
nextWorker
OKButton PrintButton
Decorator
runtime tree/
Composite graph
Client Subject
operation()
realSubject
RealSubject Proxy
...
operation() operation()
realSubject.operation()
Object Structure:
:Client
A:Proxy B:RealSubject
ref
realSubject successor
Filter proxy (smart reference): executes additional actions, when the object is
accessed
Protocol proxy: counts references (reference-counting garbage collection
or implements a synchronization protocol (e.g., reader/writer protocols)
Indirection proxy (facade proxy): assembles all references to an object to
make it replaceable
Virtual proxy: creates expensive objects on demand
Remote proxy: representative of a remote object
Caching proxy: caches values which had been loaded from the subject
Remote
Loading lazy on demand
Protection proxy
Firewall
Decorator
n sucessors possible
Shadowing
runtime list
1:1 successor relation,
1:1 successor relation
1 successor Instance of ObjectRecursion
Methods in common
Aggregation to
sister class
Proxy
Chain
Concrete
MoreConcrete MoreConcrete Concrete
HookClassB
TemplateA TemplateB HookClassA
hookMethod()
templateMethod() templateMethod() hookMethod()
// Implementation A
foreach h in hookObjects
h.hookMethod();
// Implementation B
foreach h in hookObjects
h.hookMethod();
a b c
x 60 30 10
y 50 30 20
z 80 10 10
a b c
Subject
*
Subject Observer
observers
register(Observer) update ()
unregister(Observer)
for all b in observers {
notify()
b.update ()
}
ConcreteObserver
Subject ObserverState =
ConcreteSubject update () Subject.getState()
getState() ObserverState
setState()
possible) setState()
notify()
Observer pulls data out
itself
update 1()
Due to pull of data,
subject does not care getState()
nor know, which update n()
observers are involved:
subject independent of getState()
observer
Multiple subjects:
If there is more than one subject,
send Subject as Parameter of update(Subject s).
Push model: subject sends data in notify()
The default is the pull model: observer fetches data itself
Change manager
*
Subject PushObserver
observers
update(Data)
register(PushCallBack) // push(Data)
unregister(PushCallBack
Back) for all b in observers {
notify(d:Data)
b.update (d)
}
Concrete
PushObserver
ConcreteSubject update (Data) do something with Data
ObserverState
register()
setState()
notify()
update 1(d:Data)
...
update n(d:Data)
...
manager.notify()
SimpleChangeManager DAGChangeManager
register(Subject,Observer) register(Subject,Observer)
manager.register(this,b) unregister(Subject,Observer) unregister(Subject,Observer)
notify() notify()
Basis of many interactive application frameworks (Xwindows, Java AWT, Java InfoBus, ....)
EventBus (Mediator)
Decorator
Bridge *-Bridge
ObjectRecursion Chain
Observer
unconstraining
Composite
unconstraining Dimensional
ClassHierarchies
This allows for constructing runtime nets: lists, sets, and graphs
And hence, for dynamic extension
The common superclass ensures a common contract of all objects in the
runtime net