510 likes | 526 Views
Behavioral Design Patterns. December 20, 2019. Behavioral Patterns – 1. Command Iterator Mediator Observer Strategy Template Method. Behavioral Patterns – 2. Chain of Responsibility Interpreter Momento State Visitor. Iterator. Design Purpose
E N D
Behavioral Design Patterns December 20, 2019
Behavioral Patterns – 1 • Command • Iterator • Mediator • Observer • Strategy • Template Method
Behavioral Patterns – 2 • Chain of Responsibility • Interpreter • Momento • State • Visitor
Iterator • Design Purpose • Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation • Design Pattern Summary • Encapsulate the iteration in a class pointing (in effect) to an element of the aggregate
Iterator Interface Iterator { // move to first item: void first(); // if it is at last item: boolean isDone(); // move point to next item: void next(); // Return the current: Object currentItem(); }
Using Iterator • /* • To perform desiredOperation() on items in the • container according to the iteration (order) i: • */ • Iterator i = IteratorObject; • for(i.first(); !i.isDone(); i.next()) • desiredOperation(i.currentItem());
Iterator Sample Code // Suppose that we have iterators for forward and // backward order: we can re-use print_employees() List employees = new List(); Iterator fwd = employees.createForwardIterator(); Iterator bckwd = employees.createBackwardIterator(); // print from front to back client.print_employees(fwd); // print from back to front client.print_employees(bckwd);
Using Iterator • Class Client extends … { • print_employees(Iterator it) { • for(it.first(); !it.isDone(); it.next()) { • print(i.currentItem()); • } • } • // other operations • }
Client Iterator Class Model Iterator first() next() isDone() currentItem() Container createIterator() append() remove() ConcreteIterator ConcreteContainer createIterator() return new ConcreteIterator(this)
Iterator - Question What is the difference between the two clients Class Client1 { void operation( Container c) { Iterator it = c.createIterator(); for (it.first(); it.isDone(); it.next()) { Object item = it.currentItem(); // process item } } } Class Client2 { void operation( Iterator it) { for (it.first(); it.isDone(); it.next()) { Object item = it.currentItem(); // process item } } }
Iterator - Question Iterator Container Client1 is dependent upon two interfaces: Iterator and Container Client1 Client2 is dependent upon only one interface: Iterator Client2
Iterator in Java - 1 Interface Iterator<E> { // check if there are more elements. boolean hasNext(); // Returns the next element in the iteration. E next() // Removes from the underlying collection // the last element returned by the iterator // (optional operation). void remove(); }
Iterator in Java - 2 import java.util.Iterator; public class ArrayListViaListWithIterator<E> { private Node head, tail; private int count; public ArrayListViaLinkedListWithInnerIterator() { head = null; tail = null; count = 0; } public Iterator<E> iterator() { return new ALIterator(); } public void add(int i, E e) { … } public E get(int i) { … } public boolean isEmpty() { … } public E remove(int i) { … } public E set(int i, E e) { … } public int size() { … }
Iterator in Java - 3 private class Node { private E item; private Node next; Node(E i, Node n) { … } public E getItem() { … } public void setItem(E item) {{ … } public Node getNext() { … } public void setNext(Node next) { … } }
Iterator in Java - 4 private class ALIterator implements Iterator<E> { private Node cursor; public AIIterator() { cursor = head; } public boolean hasNext() { return cursor != null; } public E next() { Node tmp = cursor; cursor = cursor.getNext(); return tmp.getItem(); } public void remove() { throw new RuntimeException("not supported"); } } // end of Iterator } // end of ArrayList
Observer • Design Purpose • Arrange for a set of objects to be affected by a single object. • Design Pattern Summary • The single object aggregates the set, calling a method with a fixed name on each member.
Observer - Structure Subject attach(Observer) detach(Observer) notify() Observer update(subject) 1..n observers for o: observers o.update(this); ConcreteObserver observerState update(Subject s) ConcreteSubject subjectState getState() setState() … s.getState(); … // change state notify();
Observer: Sequence diagram Client :Subject O1:Observer O2: Observer setState() notify() update() getState() update() getState()
Observer in Java Observable notifyObservers() attach(Observer) detach(Observer) Observer update(Observable, Object ) MyConcreteObserver observerState update(…) MyObservable subjectState subject
Observer: Key Concept -- to keep a set of objects up to date with the state of a designated object.
Mediator • Design Purpose • Avoid references between dependent objects. • Design Pattern Summary • Capture mutual behavior in a separate class.
Mediator - Model Colleague Mediator Colleague_A Colleague_B ConcreteMediator
Mediator Sequence Diagram B: Colleague_B Client :Mediator :Mediator A:Colleague_A C: Colleague_A request() mediate() takeAction_1() takeAction_2() takeAction_3()
Key Concept: Mediator -- to capture mutual behavior without direct dependency.
Command • Design Purpose • Increase flexibility in calling for a service e.g., allow undo-able operations. • Design Pattern Summary • Capture operations as classes.
Client Command - Structure Invoker +request() Command execute(); Receiver action() receiver ConcreteCommand execte() State receiver.action()
Command – Sequence Diagram R:Receiver :Client C: ConcreteCmd Invoker new ConcreteCmd( R ) new Invoker( C ) execute() action()
Command - Example command Cut:Button Clicked() command Copy:Button Clicked() Command execute(); command.execute() command.execute() CutCommand execte() CopyCommand execte() doc doc command.execute() doc.cut() doc.copy() Document copy() cut() Cut:MenuItem Selected() A B: A composed in B
Command – Setup d:Doc C:CopyCommand aClient X:CutCommand Cut:MenuItem Copy:Button new Doc() Cut:Button new CutCommand( d ) new CopyCommand( d ) new MenuItem( x ) new Button( x ) new Button( c )
Command – Sequence Diagram Cut:MenuItem Copy:Button CutCommand Document Cut:Button Command CopyCommand selected() execute() cut() clicked() execute() cut() clicked() execute() copy()
Key Concept - Command -- to avoid calling a method directly (e.g., so as to record or intercept it).
Strategy • Design Purpose • Allow the algorithm vary independently from clients that use it • Design Pattern Summary • Define a family of algorithms, encapsulate each one, and make them interchangeable
Strategy - Example Sorter sort() PlayerPool chooseTwo() sorter BubbleSorter sort() MergerSorter sort() ... sorter.sort(); ...
Strategy - Model Strategy Algorithm() Context contextInterface() strategy ConcreateStrategyA algorithm() ConcreateStrategyB algorithm() ConcreateStrategyC algorithm()
Strategy - participants • Strategy (Sorter) • Declare an interface for the family of algorithms • ConcreteStrategy (BubbleSort and MergeSort) • Implementations of the algorithms. • Context (PlayerPool) • Configured with a ConcreteStrategy object • Maintains a reference to a Strategy object • May define an interface that lets Strategy to access its data • Collaborations • Strategy and Context interact to implement the chosen algorithm. A context may make itself access to the algorithm • A context forwards requests from its clients to its strategy. Clients usually decide which ConcreteStrategy to use for the given context
Strategy – sample code Class PlayerPool { ArrayList players; Comparator c; Sorter sorter; PlayerPool(Comparator c, Sorter s) { this.c = c; this.sorter = s; } Player[] chooseTwo() { sorter.sort(players, c); players[0] = players.remove(); players[1] = players.remove(); return players; } } Interface Sorter { void sort(List list, Comparator c) } Class BubbleSort implements Sorter { void sort(List l, Comparator c) } Class MergeSort implements Sorter { void sort(List l, Comparator c) } Class Client { void main() { Player players[2]; Comparator c = new PriorityComp(); Sorter s = new BubbleSort(); PlayerPool vip = new PlayerPool(c, s); players = vip.chooseTwo(); // use players to form a game } } Actually, Comparator for sort() is a strategy in this example
Template Method • Design Purpose • Allow subclasses to redefine certain steps of an algorithm without changing the algorithm’s structure • Design Pattern Summary • Define the skeleton of an algorithm in an operations, deferring some steps to subclasses
Template Method - Example App addDoc() openDoc() createDoc() canOpenDoc() Document save() open() close() read() docs MyApp createDoc() canOpenDoc() MyDocument read() return new MyDocument()
Template Method - example • The openDoc() of App is a template method which uses steps (canOpenDoc ()and createDoc()) that are provided by subclasses (MyApp) Class App { List<Document> docs; void openDoc(String file) { if (!canOpenDoc(file)) { // cannot handle this doc return; } Document doc = createDoc(file); docs.add(doc); doc.open(); doc.read(); } }
Template Method - Model AbstractClass templateMethod() primitiveOperation1()primitiveOperation2() { // other operations primitiveOperation1(); primitiveOperations(); } ConcreteClass primitiveOperation1() primitiveOperation2()
Template Method - participants • AbstractClass (App) • Define an algorithm as an operation which uses abstract primitive operations (as steps of the algorithm) that are to be implemented by subclasses of AbstractClass • Template method may call other operations defined in AbstractClass • ConcreteClass (MyApp) • Implement the abstract primitive operations that are used in the template method. • Collaborations • ConcreteClass relies on AbstractClass to implement the invariant steps of the algorithm.
Summary • Iterator visits members of a collection • Mediator captures behavior among peer objects • Observer updates objects affected by a single object • Commandcaptures function flexibly (e.g. undo-able)
Other Patterns • Chain of Responsibility • Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request • Interpreter • Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language
Other Patterns • Memento • Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later • State • Allow an object to alter its behavior when its internal state changes.
Other Patterns • Strategy • Define a family of algorithms, encapsulate each one, and make them interchangeable. • Template Method • Define the skeleton of an algorithm in an operation, deferring some steps to subclasses