Transcript
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>