Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 1.Mediator 2.Observer 3.Chain of Responsibilitiy 4.Command 5.Strategy 6.Iterator 7.State 8.Memento.

Similar presentations


Presentation on theme: "1 1.Mediator 2.Observer 3.Chain of Responsibilitiy 4.Command 5.Strategy 6.Iterator 7.State 8.Memento."— Presentation transcript:

1 1 1.Mediator 2.Observer 3.Chain of Responsibilitiy 4.Command 5.Strategy 6.Iterator 7.State 8.Memento

2 2 Introduction f f f focused on - typical communication between objects - assignment of responsibilities between objects Class patterns inheritance for distributing responsibilities - Template method - Interpreter Object patterns - target loose coupling between communicating objects Mediator, Chain of Responsibility, Observer - encapsulate behavior in object Strategy, Command, State, Visitor, Iterator

3 3 Motivation Interaction between many objects Default solution : objects contain references to each other Worst case : for N objects -> N*(N-1) references Problem : difficult to reuse object/class ABCDE

4 4 Solution Colleagues (A,B,C,D,E) Interacting objects ONLY refer to single object “Mediator” Mediator (M) Knows all interacting objects Single point of contact Manages interaction ABCDEM

5 5 Example : Hotel cleaning Hotel has - number of Room s - number of Housekeeper s Each Housekeeper is responsible for number of Room s (Many-to-many) State of Room -available ? -clean ?

6 6 Example : Hotel cleaning

7 7 No Mediator [Hotel] class Hotel { private String name="HotelName"; private Room[] r; private Housekeeper[] h; public Hotel(String n,Room[] rr,Housekeeper[] hh) {name=n;r=rr;h=hh;} public String toString() {return "Hotel : "+name+" ";} public Room searchRoom() { for(Room ri : r) if(ri.isAvailable()&&ri.isCleaned()) return ri; for(Housekeeper hi : h) for(Room ri:r) if(ri.isAvailable()&&hi.cleanRequest(ri)) return ri; return new Room("0.0"); // no room available ! }

8 8 No Mediator [Housekeeper] class Housekeeper { private String name="HousekeeperName"; private ArrayList toClean=new ArrayList(); public Housekeeper(String n) {name=n;} public void setRoomsToClean(Room[] r) { for(Room ri:r) {toClean.add(ri);ri.addHousekeeper(this);}} public String toString() { String r= "Housekeeper : "+name; return r; } public boolean cleanRequest(Room r) { if(toClean.contains(r)) { r.clean(this); System.out.println(this+" cleaned "+r); return true; } else { System.out.println(this+" refused cleaning "+r);return false; }

9 9 No Mediator [Room] class Room { private String number; private boolean available=true; private boolean cleaned=true; private ArrayList hk=new ArrayList(); public void addHousekeeper(Housekeeper h) {hk.add(h);} public void removeHousekeeper(Housekeeper h) {hk.remove(h);} public Room(String n) {number=n;} public String toString() {return "["+number+" available :"+available+" cleaned : "+cleaned+"]";} public void book() {available=false;} public void unbook() {available=true;cleaned=false;} public void clean(Housekeeper h) { if(hk.contains(h)) {cleaned=true;} else {System.out.println("Access error : "+this);} } public boolean isCleaned() {return cleaned;} public boolean isAvailable() {return available;} }

10 10 No Mediator [Test] public class NoMediator { public static void main(String[] args) { Room[] r={new Room("1.1"),new Room("1.2"),new Room("1.3"), new Room("2.1"),new Room("2.2"),new Room("2.3")}; Housekeeper[] h={new Housekeeper("An"),new Housekeeper("Bert"), new Housekeeper("Cecilia"),new Housekeeper("Dave")}; Hotel fancy=new Hotel("Fancy Hotel",r,h); h[0].setRoomsToClean(new Room[] {r[0],r[1],r[2]}); h[1].setRoomsToClean(new Room[] {r[3],r[4],r[5]}); h[2].setRoomsToClean(new Room[] {r[0],r[3],r[1],r[4]}); h[3].setRoomsToClean(new Room[] {r[1],r[2],r[4],r[5]}); for(int i=0;i<5;i++) r[i].book(); for(int i=0;i<5;i+=2) r[i].unbook(); for(int i=0;i<5;i++) { Room room=fancy.searchRoom(); System.out.println("--> "+i+" "+room); room.book(); }

11 11 The mediated Hotel

12 12 Mediated Hotel [Mediator] class Mediator { private Housekeeper[] h; private Room[] r; private Map > m =new HashMap >(); public void setRoomsToClean(Housekeeper hi,Room[] ri) { ArrayList r=new ArrayList (); for(Room room:ri) r.add(room); m.put(hi,r); } public Mediator(Room[] ri,Housekeeper[] hi) { r=ri;h=hi; for(Room room:r) room.setMediator(this); for(Housekeeper hk:h) hk.setMediator(this); } //... }

13 13 Mediated Hotel [Mediator] class Mediator { //... public void changed(Colleague c) { for(Housekeeper hi:h) { if(hi.equals(c)) {System.out.println(this+" is cleaning...");} } for(Room ri:r) { if(ri.equals(c)) { System.out.println(" "+(Room)c+" was cleaned."); } public boolean cleanRequest(Housekeeper h,Room r) { ArrayList toClean=m.get(h); if(toClean.contains(r)) {r.clean();return true; } else { System.out.println(h+" refused cleaning "+r);return false; }

14 14 Mediated Hotel [Colleague,Room] class Colleague { protected Mediator director; public void setMediator(Mediator m) {director=m;} public void changed(){director.changed(this);} } class Room extends Colleague { private String number; private boolean available=true,cleaned=true; public Room(String n) {number=n;} public String toString() {return "["+number+"]";} public void book() {available=false;} public void unbook() {available=true;cleaned=false;} public void clean() { // anything to clean the room cleaned=true; changed(); } public boolean isCleaned() {return cleaned;} public boolean isAvailable() {return available;} }

15 15 Mediated Hotel [Housekeeper] class Housekeeper extends Colleague { private String name="HousekeeperName"; public Housekeeper(String n) {name=n;} public String toString() { String r= "Housekeeper : "+name; return r; } public void cleanRequest() { // anything to clean... changed(); } }

16 16 Mediated Hotel [Hotel] class Hotel extends Colleague { private String name="HotelName"; private Room[] r; private Housekeeper[] h; public Hotel(String n,Room[] rr,Housekeeper[] hh) {name=n;r=rr;h=hh;} public String toString() {return "Hotel : "+name+" ";} public Room searchRoom() { for(Room ri : r) if(ri.isAvailable()&&ri.isCleaned()) return ri; for(Housekeeper hi : h) for(Room ri:r) if(ri.isAvailable()&&director.cleanRequest(hi,ri) ) return ri; return new Room("0.0"); // no room available ! }

17 17 Mediated Hotel [Test] public class WithMediator { public static void main(String[] args) { Room[] r={new Room("1.1"),new Room("1.2"),new Room("1.3"), new Room("2.1"),new Room("2.2"),new Room("2.3")}; Housekeeper[] h={new Housekeeper("An"),new Housekeeper("Bert"), new Housekeeper("Cecilia"),new Housekeeper("Dave")}; Hotel fancy=new Hotel("Fancy Hotel",r,h);Mediator m=new Mediator(r,h); m.setRoomsToClean(h[0],new Room[] {r[0],r[1],r[2]}); m.setRoomsToClean(h[1],new Room[] {r[3],r[4],r[5]}); m.setRoomsToClean(h[2],new Room[] {r[0],r[3],r[1],r[4]}); m.setRoomsToClean(h[3],new Room[] {r[1],r[2],r[4],r[5]}); fancy.setMediator(m); for(int i=0;i<5;i++) r[i].book(); for(int i=0;i<5;i+=2) r[i].unbook(); for(int i=0;i<5;i++) { Room room=fancy.searchRoom(); System.out.println("--> "+i+" "+room);room.book(); }

18 18 General Solution Mediator : defines interface to communicate with Colleague s ConcreteMediator : - coordinates Colleague objects - knows and manages Colleague collection Colleague : - knows Mediator object - communicates through Mediator with Colleague s

19 19 Consequences 1.limits subclassing changing behaviour : subclass Mediator instead of all Colleague s 2.Decouples Colleague s 3.Simplifies object protocols replaces many-to-many by one-to-many 4.Interaction between Colleague s in one class only (separates behavior associated with collaboration and own behavior) 5.Centralizes control Mediator can become complex

20 20 Implementation Abstract Mediator class -allows Colleague s to engage in multiple cooperations -can be avoided (see Hotel example) in case of 1 cooperation only Communication Mediator – Colleagues Mediator should be notified of important events -use Observer pattern -Mediator = Observer -Colleague = Subject -Mediator reacts upon events from Colleague s -Special notification (see Hotel example)

21 21 Motivation Organise efficiently one-to-many relations between objects ABCD - propagate state changes of A to B, C and D - dynamically manage collection of objects to notify - objects to notify not known in advance heavily used in - MVC based systems - event based systems (publish-subscribe) - Mediator-Colleague communication

22 22 Example : Cleaning notification

23 23 Hotel cleaning class Hotel { // as before public void notifyCleaned(Room r) { System.out.println("Hotel "+this+" room "+r+" cleaned."); } class Housekeeper { // as before public void notifyCleaned(Room r) { System.out.println(this+" received message cleaning room "+r); }

24 24 Hotel cleaning class Room { // as before private Hotel h; private ArrayList hk=new ArrayList(); public void setHotel(Hotel hi) {h=hi;} public void addHousekeeper(Housekeeper h) {hk.add(h);} public void removeHousekeeper(Housekeeper h) {hk.remove(h);} public void clean(Housekeeper h) { if(hk.contains(h)) { cleaned=true; for(Housekeeper hh:hk) hh.notifyCleaned(this); h.notifyCleaned(this); } else { System.out.println("Access error to clean room "+this); } // test code as before (see code for no mediator)

25 25 Observer solution

26 26 Observed hotel cleaning class Subject { private ArrayList l=new ArrayList (); public void add(Observer o) {l.add(o);} public void remove(Observer o) {if(l.contains(o)) l.remove(o);} public void notifyObservers() {for(Observer o:l) o.update(this);} } interface Observer { void update(Subject s); } class Hotel implements Observer { // as before... public void update(Subject s) { System.out.println("Hotel "+this+" room "+s+" cleaned."); }

27 27 Observed hotel cleaning class Housekeeper implements Observer { // as before... public void update(Subject s) { System.out.println(this+" received message cleaning room "+s); } class Room extends Subject { // as before, NO Hotel aggregate object public void clean(Housekeeper h) { if(hk.contains(h)) { cleaned=true; notifyObservers(); } else { System.out.println("Access error to clean room "+this); } // main test method as before

28 28 General solution

29 29 General solution Subject - knows all Observer s watching - provides interface for adding/removing Observer s Observer : defines update-interface for observing objects ConcreteSubject - stores relevant state for ConcreteObserver s - notifies when relevant state changes ConcreteObserver - has reference to ConcreteSubject (possibly through update()) - implements Observer interface, keeps state consistent

30 30 General solution

31 31 Consequences 1.Abstract coupling of Subject and Observer s reuse of Subject / Observer code Can belong to different parts of the system to build 2.Facilitates broadcasts message destinations can be specified at runtime 3.Unexpected updates Subject does not know effect of sending update message cascade of updates standard patterns does not indicate WHAT is changed

32 32 Implementation issues 1.Many Subject s, few Observer s -> store relation in HashMap 2.Observing more than 1 Subject Identify sending object (e.g. by passing this-reference in update) 3.Update responsibility 1.Subject calls notify : + guarantee for consistency - low update granularity 2.Client calls notify - no guarantee for consistency (client might forget) + more efficient through coarser granularity 4.Dangling references when Subject is deleted Subject should notify Observer s prior to deletion 5.Subject state should be consistent PRIOR to notification !

33 33 Implementation issues 6.Push – Pull ? push : - Subject sends info on change to Observer s - can introduce unwanted dependency / reduced reuse pull : - Observer requests info from Subject after being notified - possibly inefficient 7.Update granularity enhance Subject interface to allow registration for specific state updates (e.g. one field only, large changes only, etc.) add(Observer o, Aspect a) update(Subject s, Aspect a) 8.Complex updates in case of complex dependencies -> use ChangeManager e.g. organise updates in Directed Acyclic Graph to reduce updates

34 34 Chain of Responsibility Motivation : Decouple Sender and Handler of request Set of Handlers can fulfill request Set is ordered in linked list ClientBCD Usage : - if handler is not known beforehand - Client code abstract in terms of handler - chain should be configured dynamically Handlers

35 35 General Solution handleRequest : recursive call down the chain Client : initiates request Handler : - defines interface for request handling - knows how to find successor in chain (can be deferred to subclass) ConcreteHandler : - handles request if responsible, or forwards otherwise - can access successor

36 36 Consequences Implementation Consequences 1.Reduced coupling client does not know object that will eventually handle request reduced inter-object links (easier to maintain) 2.Flexible distribution of responsibilities change the chain at runtime 3.No guarantee the request will be handled ! Implementation issues 1. Defining the chain new links (linked list is popular choice) existing links (e.g. containment hierarchy) 2. Request representation simple hard coded request type of request encoded (int, String,...) -> handler decodes request type and decides whether to handle or forward

37 37 Implementation Issues 1.Defining the chain 1.new links (linked list is popular choice) 2.existing links (e.g. containment hierarchy) 2.Request representation 1.simple hard coded request 2.type of request encoded (int, String,...) -> handler decodes request type and decides whether to handle or forward

38 38 Motivation Motivation : - functor mechanism : function is first class object - decouple client from server and exact command to execute - provide facilities to - queue requests - log requests - undo/redo requests Example : interface toolkit - commands will travel from UI to handling objects - content/meaning of command not known when toolkit developed Usage : - to parametrize objects by an action to perform - time decoupling : specify – queue – execute request (Command can live longer than requestor) - undo : Command can know how to undo itself.

39 39 Example : book hotel rooms

40 40 Example : Hotel class Hotel { private String name="HotelName"; private Room[] r; public Hotel(String n,Room[] rr) {name=n;r=rr;} public String toString() { String s=""; for(Room rr:r) s+=rr;return "Hotel : "+name+" "+s; } public Room searchRoom() { for(Room ri : r) if(ri.isAvailable()) return ri; return new Room("0.0"); // no room available ! } public boolean bookRoom(Room rr) { boolean ok=rr.isAvailable(); if(ok) rr.book(); return ok; }

41 41 Example : Room class Room { private String number; private boolean available=true; public Room(String n) {number=n;} public String toString() { return "["+number+" available :"+available+"]"; } public void book() {available=false;} public void unbook() {available=true;} public boolean isAvailable() {return available;} }

42 42 Example : Commands [1] interface Command { void execute(); } abstract class HotelCommand implements Command { protected Hotel h; protected Room r; public HotelCommand(Hotel hh,Room rr) {h=hh;r=rr;} abstract public void execute(); public Room getRoom() {return r;} } class BookCommand extends HotelCommand { public BookCommand(Hotel hh,Room rr) {super(hh,rr);} public void execute() { h.bookRoom(r); }

43 43 Example : Commands [2] class SearchCommand extends HotelCommand { public SearchCommand(Hotel hh) {super(hh,null);} public void execute() { r=h.searchRoom(); } } class SearchBookCommand extends HotelCommand { public SearchBookCommand(Hotel hh) {super(hh,null);} public void execute() { SearchCommand sc=new SearchCommand(h); sc.execute(); r=sc.getRoom(); BookCommand bc=new BookCommand(h,r); bc.execute(); }

44 44 Example : TravelAgency class TravelAgency { private ArrayList cl=new ArrayList (); public void addCommand(Command c) {cl.add(c);} public void execute() { for(Command c:cl) c.execute();// make list empty ? } // could also be Command (composite)

45 45 Example : Test code public static void main(String[] args) { Room[] rfancy={new Room("1.1"),new Room("1.2"),new Room("1.3"), new Room("2.1"),new Room("2.2"),new Room("2.3")}; Hotel fancy=new Hotel("Fancy Hotel",rfancy); Room[] rmayfair={new Room("A.1"),new Room("A.2"),new Room("A.3"), new Room("B.1"),new Room("B.2"),new Room("B.3")}; Hotel mayfair=new Hotel("Mayfair Hotel", rmayfair); BookCommand bc=new BookCommand(fancy, rfancy[2]); TravelAgency tui=new TravelAgency(); tui.addCommand(bc); tui.execute();// book room SearchBookCommand[] sc=new SearchBookCommand[8]; // search&book 8 rooms for(int i=0;i

46 46 General Solution Command : provides interface to execute operation ConcreteCommand : - knows Receiver - execute : invoke action on receiver Client : - create ConcreteCommand s - set Receiver for Command s Invoker : causes Command s to execute Receiver : implements logic of operation

47 47 General Solution

48 48 Consequences Implementation Consequences Decoupling of invoker and logic implementation (functional and in time) Commands are first class objects (“functors”) Composite Commands can be constructed (Composite design pattern) Easy to add new Commands Implemention 1.Commands intelligence just dispactching does everything (no receiver) finds receiver dynamically (at runtime) 2.Support for undo/redo 3.Error accumulation in undoing

49 49 Undo/Redo Undoable Commands : - extend interface with undo() - additional state : - Receiver object - arguments used when invoking action on receiver - state of Receiver prior to invoking action BUT : Receiver must support operations for restoring prior state Application changes : 1 level of undo : just keep track of last Command many levels : keep history list of Command s Make deep copy of Command ! (e.g. use Prototype design pattern) Accumulating errors : problem : undo/redo not entirely inverse operations Solution : make copy of prior state of more objects (Use Memento design pattern)

50 50 Motivation Allow to select algorithm at runtime Alternative algorithms belong to same family Usage : - configure classes/object with behavior many alternative behaviors each alternative is strategy - different algorithmic flavours, specialized in dedicated situations - hide algorithm specific data from client objects

51 51 Example : Strategic Hotel - searching Room : delegated to SearchStrategy - SearchStrategy has access to its data (the Room s) through Hotel object (“Context”)

52 52 Example : Hotel + Room class Hotel { private String name="HotelName"; private Room[] r; private SearchStrategy s; public void setSearchStrategy(SearchStrategy ss){s=ss;s.setHotel(this);} public Room[] getRooms() {return r;} // context interface public Hotel(String n,Room[] rr) {name=n;r=rr;} public String toString() {String s="";for(Room rr:r) s+=rr; return "Hotel : "+name+" "+s;} public Room searchRoom() {return s.searchRoom(); /* delegation ! */} public boolean bookRoom(Room rr) { boolean ok=rr.isAvailable(); if(ok) rr.book(); return ok; } class Room { // as before }

53 53 Example : Strategies abstract class SearchStrategy { protected Hotel h; public abstract Room searchRoom(); void setHotel(Hotel hh) {h=hh;} } class RandomSearchStrategy extends SearchStrategy { public Room searchRoom() { Room[] r=h.getRooms(); int i=(int)(Math.random()*r.length); return r[i]; } class FirstAvailableStrategy extends SearchStrategy { public Room searchRoom() { Room[] r=h.getRooms(); for(Room ri:r) if(ri.isAvailable()) return ri; Room zero=new Room("0.0");zero.book();return zero; }

54 54 Example : Test code public static void main(String[] args) { Room[] rfancy={new Room("1.1"),new Room("1.2"),new Room("1.3"), new Room("2.1"),new Room("2.2"),new Room("2.3")}; Hotel fancy=new Hotel("Fancy Hotel",rfancy); Room[] rmayfair={new Room("A.1"),new Room("A.2"),new Room("A.3"), new Room("B.1"),new Room("B.2"),new Room("B.3")}; Hotel mayfair=new Hotel("Mayfair Hotel", rmayfair); fancy.setSearchStrategy(new RandomSearchStrategy()); mayfair.setSearchStrategy(new FirstAvailableStrategy()); for(int i=0;i<10;i++) System.out.print(fancy.bookRoom(fancy.searchRoom())+" "); System.out.println(""); for(int i=0;i<10;i++) System.out.print(mayfair.bookRoom(mayfair.searchRoom())+" "); } true false true false true true true false true false true true true true true true false false false false sample output

55 55 General Solution Strategy : declares common interface for all algorithms ConcreteStrategy : implements the interface Context : - configured with ConcreteStrategyX object - typically provides interface to Strategy to receive input

56 56 Consequences 1.Helpful to organize algorithms in hierarchy (avoid code duplication) 2.Why not subclass Context directly : not dynamically configurable introduces many classes with limited differences hard to reuse algorithm itself 3.Configurable behavior easier/cleaner than conditionals 4.Runtime configuration allows to choose best algorithm for given conditions 5.Clients must know different strategies 6.Communication overhead between Strategy and Context (too much info passed to Strategy ) 7.Increased number of objects

57 57 Implementation 1.Interfacing between Context and Strategy Options pass all data as method arguments (can be too much) pass Context reference to Strategy (tighter coupling) 2.Optional Strategy If no Strategy specified : default behaviour If Strategy present : use Strategy (e.g. Comparables in Java Collections Framework)

58 58 Motivation Provide unified method to access sequentially objects in aggregating object, hiding underlying implementation Usage : - support easy object traversal without revealing internals - support multiple ways to traverse object - support polymorphic iteration Used in almost all data structure libraries (C++ STL, Java Collection Framework,.NET Collections)

59 59 General Solution Iterator : defines interface for traversing ConcreteIterator : - implements Iterator interface, - keeps track of current position Aggregate : defines interface for creating Iterator ConcreteAggregate : implements Iterator creation Java : inner class C++ : friend class

60 60 Consequences Implementation Consequences 1.Aggregate s can be iterated through in various ways (just implement the proper ConcreteIterator ) 2.The interface of the Aggregate becomes simpler 3.Various Iterator s can be active on same Aggregate simultaneously Implementation 1.Iteration control external : client requests Iterator to advance, does operation on current element, etc. -> complexer, general usage internal : client gives operation to Iterator, and Iterator applies operation on each element -> easier, but less applicable 2.Traversal algorithm Iterator itself Aggregate ( Iterator is merely cursor)

61 61 Implementation 3. Iterator robustness - dangerous to change Aggregate while iterating -> expensive solution : make copy and iterate over copy - robust Iterator -> gets notified by Aggregate when it changes -> adapts accordingly 4. Additional Iterator methods - skipTo, previous, Iterator access - in C++ : friend class to allow access to Aggregate data - in Java : inner class 6. Iterating over Composite s - external : requires storage of path through the recursive structure - internal : easier to implement (recursive call to itself) 7. NullIterator - trick to mark leaves of terminals

62 62 Motivation Change object behavior based on internal state Avoid testing on state variables in all methods s1s2s3 if (state==s1) {... } else if (state==s2) {... } else {... } Usage - object behavior (heavily) depends on runtime state - a lot of methods would contain excessive state testing

63 63 Example : Room state Room state diagram : - (not) available - dirty/clean Methods : - book - unbook - guestEnters - clean self-transitions not shown

64 64 Example : Room state state.book(this)

65 65 Example : Room class Room { private State s=new AvailableClean(); private String number; public void setState(State ss) {s=ss;} public Room(String n) {number=n;} public String toString() {return "["+number+" : "+s+"]";} public boolean book() {return s.book(this);} // delegate to state public boolean unbook() {return s.unbook(this);} public boolean clean() {return s.clean(this);} public boolean guestEnters() {return s.guestEnters(this);} }

66 66 Example : State interface State { boolean book(Room r); boolean unbook(Room r); boolean clean(Room r); boolean guestEnters(Room r); } class AvailableClean implements State { public boolean book(Room r) { r.setState(new NotAvailableClean()); return true; } public boolean unbook(Room r) {return false;} public boolean clean(Room r) {return false;} public boolean guestEnters(Room r) {return false;} public String toString() {return "Available & Clean";} }

67 67 Example : State class NotAvailableClean implements State { public boolean book(Room r) {return false;} public boolean unbook(Room r) { r.setState(new AvailableClean()); return true; } public boolean clean(Room r) {return false;} public boolean guestEnters(Room r) { r.setState(new NotAvailableDirty()); return true; } public String toString() {return "Not Available & Clean";} }

68 68 Example : State class NotAvailableDirty implements State { public boolean book(Room r) {return false;} public boolean unbook(Room r) { r.setState(new AvailableDirty()); return true; } public boolean clean(Room r) { r.setState(new NotAvailableClean()); return true; } public boolean guestEnters(Room r) {return false;} public String toString() {return "Not Available & Dirty";} }

69 69 Example : State class AvailableDirty implements State { public boolean book(Room r) {return false;} public boolean unbook(Room r) {return false;} public boolean clean(Room r) { r.setState(new AvailableClean()); return true; } public boolean guestEnters(Room r) {return false;} public String toString() {return "Available Dirty";} } // test code... Room r=new Room("1.0");System.out.println(r); r.book();System.out.println(r); r.guestEnters();System.out.println(r); r.book();System.out.println(r);

70 70 General Solution Context : refers ConcreteStateX, current state of the object State : defines interface for behavior of Context object ConcreteState : implements associated behavior

71 71 Consequences 1.Localizes state-specific behavior -> but : more classes -> results in clearer code, especially for large number of states 2.Makes transitions explicit more explicit that simply changing object variables protection against inconsistent (or non-existing) states 3.Sharing of state objects if no instance variables in state objects

72 72 Implementation 1.Performing state transitions Context object : easy if sequence fixed State object : - maps to state transition diagram - requires interface in Context to set state - but : introduces interdependencies in states 2.Table based state transitions - make table (current state, input, next state) - requires table lookup to determine next state + change in state transition diagram is only change in data (instead of changing code...) 3.Creation of state objects - when needed - beforehand

73 73 Motivation Capture object state WITHOUT violating encapsulation Facilitate restoring object current state to past state Usage : - when public interface is not sufficient to capture state - facilitate checkpointing - facilitate undo commands - in Java : serialization can be used

74 74 Example : Memento Room

75 75 Example : Memento Room class Housekeeper {/* as before */} class Room { private String number; private boolean available=true, cleaned=true; private ArrayList hk=new ArrayList (); // as before public RoomMemento createMemento() {return new RoomMemento();} public void setMemento(RoomMemento m) { number=m.n;available=m.a;cleaned=m.c;hk=m.h;} class RoomMemento { private String n; private boolean a,c; private ArrayList h=new ArrayList (); private RoomMemento() { n=number;a=available; c=cleaned;h=(ArrayList)(hk.clone()); }

76 76 Example : Memento Room public static void main(String[] args) { Room r=new Room("1.5"); Room.RoomMemento rm=r.createMemento(); r.book(); System.out.println(r); r.setMemento(rm); System.out.println(r); }

77 77 General Solution Memento : - stores internal state of Originator (just enough to restore) - has two interfaces (wide and narrow) Originator : - creates Memento - uses Memento to restore internal state Caretaker : - manages Memento s - does not inspect or manipulate Memento state wide narrow

78 78 General Solution

79 79 Consequences Implementation Consequences 1.Maintain the encapsulation principle Originator state not exposed to “everybody” 2.Simplifies Originator Version management of Originator done by client 3.Memento potentially expensive deep copies incur high overhead 4.Language must support large and narrow interface 5.Hidden costs Caretaker does not know implications of storing Memento s Implementation 1. Language support for wide and narrow interface - Java : inner class, package visibility,... - C++ : declare friend class 2. Enrich Memento -interface to support incremental changes avoid copying everything...


Download ppt "1 1.Mediator 2.Observer 3.Chain of Responsibilitiy 4.Command 5.Strategy 6.Iterator 7.State 8.Memento."

Similar presentations


Ads by Google