DESIGN PATTERNS Decorator, Proxy, Iterator and Observer (MVC) Dr Simon Spacey

DESIGN PATTERNS
Decorator, Proxy, Iterator and Observer (MVC)
Dr Simon Spacey
B.Sc. Hons. (York), M.Sc. (Lancaster), M.B.A. (Cass), J.L.P. (Keio),
D.E.A. (Montpellier), D.CSC. (Cambridge), D.I.U. (Imperial), Ph.D. (Imperial)
© Simon Spacey.
20/05/2013
<1>
What are Design Patterns?
¡  Design Patterns:
¡  Are Ways to Solve OOL Implementation Problems...
¡  ... that often have Trivially Obvious “Imperative” Solutions
¡  Popularised by the 1995 Book by Erich Gamma et al.
¡  Are often Supported by Libraries in OOLs
¡  Design Patterns Include:
¡  Creational:
Factory, Abstract Factory, Builder
Prototype, Singleton
¡  Structural:
Adapter (DAO), Bridge, Composite,
Decorator, Façade, Flyweight, Proxy
E. Gamma, R. Helm, R. Johnson, J.
Vlissides, Design Patterns, Addison
Wesley, 1995
¡  Behavioural: Chain of Responsibility, Command, Interpreter, Iterator, Mediator,
Memento, Observer (MVC), State, Strategy, Template, Visitor
© Simon Spacey.
18/04/2013
<2>
Decorator: Overview
¡  The Decorator Pattern Wraps One or More of a Classes Methods and
Optionally Adds New Methods:
Similar to an Adapter,
¡  Useful as a filter to log or change functionality
Except Adapter
Changes the Interface
¡  Notes:
¡  Is a Concrete Class with Associated Relations Embedded at Run-time
¡  Positives and Negatives:
ü  Supports Cross-Cutting Concerns (e.g. Adding Pre/Post-Logging to Subclasses)
ü  Solves Inability to call ((Cast)o).method() in Java (ok in C, C++, Objective-C)
ü  Allows Recursive Nesting (does not change the Superclass’s interface)
ü  Dynamic Runtime Instance Wrapping
✘  Extra Layer of Programming Indirection (Code Complication)!
!
© Simon Spacey.
18/04/2013
<3>
Decorator: UML
1
Base Class
+doSomething()
Associated/ Has-A
relation meaning
externally managed
Decorator
ConcreteChild
-wrapped : Base Class
+doSomething()
+doSomething()
1
// Pre-Processing
wrapped.doSomething();
// Post-Processing
An Example UML Diagram Illustrating the Decorator Design Pattern
© Simon Spacey.
18/04/2013
<4>
Decorator: Example
¡  Before:
¡  After:
!
!
...!
...!
!
!
!
!
!
!
"!
// Initialises the Pacman Pills, Power Pills and Ghosts!
public void initialise() {!
Wraps the eat()
method to beep when
pill eaten*
!
"!
// Initialises the Pacman Pills, Power Pills and Ghosts!
public void initialise() {!
!
Pill pill = new Pill1(); // finalize()=default!
!
Pill pill = new BeepPill(new Pill1()); // finalize()=beep!
!
...!
...!
!
!
!
!
displayList.add(pill.newInstance(x, y));!
displayList.add(pill.newInstance(x, y));!
!
!
!
!
...!
...!
!
!
}!
!
}!
!
...!
newInstance()
also Decorated to
return a BeepPill
...!
!
* There is no guarantee delete will call finalize() except if manually call System.gc() in Java. Hence we could need say an eat()
method to remove a pill from the display list.
© Simon Spacey.
18/04/2013
<5>
Proxy: Overview
¡  The Proxy Design Pattern is a Surrogate for Another Object:
¡  The Proxy can be used to allow Late/Demand Based or Remote Instantiation!
Similar to Decorator except for “Intent”: Late Binding and
Remote Instantiation and Controlling Access
¡  Notes:
¡  The Proxy can Execute Some Code Locally and Only Call the Real Object for Large Fns
¡  Positives and Negatives:
ü  Can Delay Objects Instantiation (Virtual Proxy)!
ü  Supports Object Migration (Remote Proxy)
ü  Can add Access Control (e.g. Smart Pointers, COW, Protection and Synchronization)
✘  Extra Layer of Programming Indirection (Code Complication)
© Simon Spacey.
18/04/2013
<6>
Proxy: UML
A Dependence in
Some Sense
Client
«interface»
Interface
+doSomething()
Real
Proxy
+doSomething()
«uses»
+doSomething()
An Example UML Diagram Illustrating the Proxy Design Pattern
© Simon Spacey.
18/04/2013
<7>
Proxy: Example
¡  Before:
¡  After:
!
!
import java.sql.*;!
!
...!
!
...!
!
!
//*** Simple Adapter between JDBC and the Application!
public class DAO implements DAOInterface {!
//*** Simple Virtual Proxy for DAO!
public class DAOProxy implements DAOInterface {!
!
!
!
!
private Connection c = null; // initialised by...!
private Statement s = null; // ... instance...!
private RecordSet r = null; // ... constructor!
private DAO dao = null;!
!
!
!
...!
public synchronized unsigned int getHighScore() {!
r
= s.executeQuery("SELECT MAX(score) FROM scores");!
return (r.next() ? r.getInt(1) : 0);!
}!
...!
...!
public synchronized unsigned int getHighScore() {!
if(dao==null) dao = new DAO(); // late init of c, s and r!
return dao.getHighScore();!
}!
...!
}!
}!
!
!
...!
...!
!
© Simon Spacey.
18/04/2013
<8>
Iterator: Overview
¡  The Iterator Design Pattern Provides a Consistent Interface for Iterating over
Disparate Collections:
¡  Can use the same code to iterate over Link Lists, Skip Lists, Arrays, Trees etc…!
¡  Notes:
¡  Each Collection must Return a Specific Iterator with Appropriate Internal Knowledge
¡  Positives and Negatives:
ü  Provides a Standard Interface for Iterating over Disparate Collections
ü  Can have Multiple Iterators at Different Points in one Collection
ü  Can have Different Iteration Algorithms (e.g. Forward and Backward)
✘  Collection Modification may need to be Synchronized with Active Iterators (!Robust)
✘  Having an Iterator Does not Enforce Consistent Collection Access Interfaces
© Simon Spacey.
18/04/2013
<9>
Iterator: UML
A Collection
Instance Could Be a
Self Iterator
«interface»
Iterable
+iterator() : Iterator
+iterator() : Iterator
Associations with
TreeIterator not shown
© Simon Spacey.
18/04/2013
+hasNext() : bool
+next() : Object
+remove()
LinkedList
TreeList
«interface»
Iterator
+iterator() : Iterator 0..1
1
ListIterator
TreeIterator
+hasNext() : bool
+next() : Object
+remove()
+hasNext() : bool
+next() : Object
+remove()
An Example UML Diagram Illustrating the Iterator Design Pattern
<10>
Iterator: Example
¡  Before:
¡  After:
...!
public class DisplayList {!
private DisplayItem first
private DisplayItem last
...!
}!
...!
import java.util.Iterator;!
...!
public class DisplayList implements Iterable, Iterator {!
private DisplayListLink first
= null;!
private DisplayListLink last
= null;!
private DisplayListLink current = null; // iterator state !
...!
// Our simple non-reentrant self Iterator initialiser!
public Iterator iterator() {!
this.current
= first; !
return (Iterator)this;!
}!
...!
This is the “foreach” loop
}!
form in Java – works for
...!
!
!
= null;!
= null;!
!
!
!
!
!
!
!
public class GUIEngine {!
...!
// Triggers each of the displayList elements to draw!
public void draw() {!
DisplayItem item
= displayList.first();!
while(item!=null) {!
item.draw();!
item
= item.next;!
}!
}!
...!
}!
...!
© Simon Spacey.
18/04/2013
<11>
!
java.util.Iterator
!
implementations and arrays
!
public class GUIEngine {!
...!
// Triggers each of the displayList elements to draw!
public void draw() {!
for(Object item : displayList) ((DisplayItem)item).draw();!
}!
...!
Cast here because not
}!
used “Generics”
...!
Observer (MVC): Overview
¡  The Observer Pattern Notifies a Set of Registered Observers on an Object’s
State Change or the Occurrence of an Event:
C Callbacks in OOP
¡  In MVC the Model (M) can notify Viewers (V) on Changes Due to Controller (C) Events
¡  Notes:
¡  Generally, the Observer is Only Notified and has to Query the Modified State It Self
¡  Positives and Negatives:
ü  Allows Consistent Viewers on Same Data (Many-to-One Dependency)
ü  Allows Abstract Coupling (Observers Need Not be Statically Related)
ü  Observers may be able to Absorb Notifications (c.f. JavaScript Event Bubbling)
✘  Observers may be Notified on Inappropriate Changes (Need Subject Lists)
✘  Changes to Model need to be Atomic/ Consistent (While Notify may Block Updates)
© Simon Spacey.
18/04/2013
<12>
Observer (MVC): UML
«interface»
Observer
Observable
+addObserver()
+deleteObserver()
+notifyObservers()
+update()
Associations with
Model not shown
Model
Controler
1
0..*
+setData()
View1
1
0..*
+update()
An Example UML Diagram Illustrating the Observer (MVC) Design Pattern
© Simon Spacey.
18/04/2013
<13>
View2
+update()
Observer (MVC): Example
¡  Before:
¡  After:
!
import android.view.*;!
!
...!
!
import android.view.*;!
import java.util.*;
...!
!
"// has Observer implementation!
!
!
public class GUIEngine extends View {!
public class GUIEngine extends View {!
!
!
private float x;
"// access through getters...!
private float y;
"// ... to stop write access!
private Observable xyObservers = new Observable(); !
...!
...!
!
!
!
!
// Sends the current touched location to the GameEngine!
@Override!
public boolean onTouchEvent(MotionEvent ev) {!
...!
gameEngine.setDirection(x, y);!
...!
}!
...!
// Sends the current touched location to all Observers!
@Override!
public boolean onTouchEvent(MotionEvent ev) {!
...!
xyObservers.notifyObservers();!
...!
}!
Now we can have say a
...!
swipeable control panel too
}!
!
!
public class GameEngine implements Observer {!
...!
public void setDirection(float x, float y) {...}!
...!
}!
public class GameEngine implements Observer {!
...!
public void update(Observable o, Object arg) {...}!
...!
}!
!
}!
!©
Simon Spacey.
18/04/2013
<14>
Summary
¡  Design Patterns:
¡  Are Ways to Solve OOL Implementation Problems...
¡  ... that often have Trivially Obvious “Imperative” Solutions
¡  Popularised by the 1995 Book by Erich Gamma et al.
¡  Are often Supported by Libraries in OOLs
¡  Design Patterns Include the:
¡  Decorator Pattern
– A Filter that can Add Functionality by Wrapping an Object!
¡  Proxy Pattern
– Delays Instantiation or Allows Remote Invocation
¡  Iterator Pattern
– Standard Interface to Iterate over a Collection
¡  Observer (MVC) Pattern – Model Notifies One or More Viewers on State Change
© Simon Spacey.
18/04/2013
<15>