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>
© Copyright 2024