1 / 23

Pattern Games

Pattern Games. CS 236700: Software Design Winter 2004-2005/T9. Overview of the programs. Three similar programs Each one is actually a single collaboration The main goal: manage a Vector of integer values The programs are similar but not identical

paytah
Download Presentation

Pattern Games

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Pattern Games CS 236700: Software Design Winter 2004-2005/T9

  2. Overview of the programs • Three similar programs • Each one is actually a single collaboration • The main goal: manage a Vector of integer values • The programs are similar but not identical • The differences are in specific details of the required behavior • We will use Design Patterns to address the various needs: • Command • Observer • Chain-of-Responsibility

  3. Participating classes • Client – the “application”. • Has a constructor and a run() method • Role: Client • PowerVector – Maintains a list of Objects • Role: Invoker, Concrete Subject, Concrete Handler • SizeKeeper – Notified when an add/remove request happens • Allows the client to obtain the size of the PowerVector object • Role: Receiver, Concrete Observer • Additional classes in each program • SizeCommand, IObserver, …

  4. Skeleton of class PowerVector public class PowerVector { private Vector items_ = new Vector(); public PowerVector(...) { ... } public Object get(int index) { return items_.get(index); } public void add(Object o) { items_.add(o); } public void remove() { items_.remove(items_.size() - 1); } }

  5. Skeleton of class Client public class Client { private PowerVector vec_; public Client() { ... } public void run() { // add 25 integers to vec_ (how?) // print size (how?) for(int i = 0; i < 3; ++i) vec_.remove(); // print size (how?) } public static void main(String[] args) { Client c = new Client(); c.run(); } }

  6. 1st program • In this program, class PowerVector has no getSize() method • A SizeKeeper object will monitor the size of the vector • We will use the Command pattern to notify the SizeKeeper object of add/remove operations

  7. Command: intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

  8. SizeKeeper public class SizeKeeper { private int size_ = 0; public void incSize(int diff) { size_ += diff; } public int getSize() { return size_; } }

  9. ICommand, SizeCommand public interface ICommand { public void execute(); } public class SizeCommand implements ICommand { private int diff_; private SizeKeeper keeper_; public SizeCommand(SizeKeeper keeper, int diff) { diff_ = diff; keeper_ = keeper; } public void execute() { keeper_.incSize(diff_); } }

  10. PowerVector public class PowerVector { private Vector items_ = new Vector(); private ICommand on_add_; private ICommand on_remove_; public PowerVector(ICommand on_add, ICommand on_remove) { on_add_ = on_add; on_remove_ = on_remove; } public void add(Object o) { items_.add(o); on_add_.execute(); // add notification } public void remove() { items_.remove(items_.size() - 1); on_remove_.execute(); // remove notification } }

  11. Client public class Client { private PowerVector vec_; private SizeKeeper keeper_ = new SizeKeeper(); public Client() { ICommand onInc = new SizeCommand(keeper_, 1); ICommand onDec = new SizeCommand(keeper_, -1); vec_ = new PowerVector(onInc, onDec); } public void run() { for(int i = 0; i < 25; ++i) vec_.add(new Integer(i)); System.out.println("Size=" + keeper_.getSize()); for(int i = 0; i < 3; ++i) vec_.remove(); System.out.println("Size=" + keeper_.getSize()); } // main() omitted }

  12. 2nd program • Now, class PowerVector provides a getSize() method • SizeKeeper will use this method • => Tight-coupling between SizeKeepr and PowerVector • SizeKeeper is an observer of PowerVector

  13. Observer: intent Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

  14. IObserver, SizeKeeper public interface IObserver { public void update(PowerVector subject); } public class SizeKeeper implements IObserver { private int size_; public SizeKeeper() { } public void update(PowerVector subject) { size_ = subject.getSize(); } public int getSize() { return size_; } }

  15. PowerVector public class PowerVector { private Vector items_ = new Vector(); private LinkedList observers_ = new LinkedList(); public PowerVector() { } public int getSize() { return items_.size(); } public void addObserver(IObserver o) { observers_.add(o); } public void add(Object o) { items_.add(o); for(Iterator i = observers_.iterator(); i.hasNext(); ) ((IObserver) i.next()).update(this); } // remove() is similarly implemented }

  16. Client public class Client { private PowerVector vec_ = new PowerVector(); private SizeKeeper keeper_ = new SizeKeeper(); public Client() { vec_.addObserver(keeper_); } public void run() { for(int i = 0; i < 25; ++i) vec_.add(new Integer(i)); System.out.println("Size=" + keeper_.getSize()); for(int i = 0; i < 3; ++i) vec_.remove(); System.out.println("Size=" + keeper_.getSize()); } // main() omitted }

  17. 3rd program • At this stage, we would like to control the values added to the PowerVector object • The Chain-Of-Responsibility allows screening of requests • Client class will invoke an “add element” request • The request will propagate through a chain of request handlers • The last handler is the PowerVector object itself

  18. Chain-of-Reponsibility: intent Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

  19. RequestHandler public class RequestHandler { private RequestHandler next_ = null; public void attach(RequestHandler other) { other.next_ = this.next_; this.next_ = other; } public final void invoke(Integer val) { if(this.handle(val)) return; if(next_ != null) next_.invoke(val); } public boolean handle(Integer val) { return false; } }

  20. EvenFilter, PrimeFilter public class EvenFilter extends RequestHandler { public boolean handle(Integer val) { return (val.intValue() % 2 == 0); } } public class PrimeFilter extends RequestHandler { public boolean handle(Integer val) { int n = val.intValue(); for(int i = 2; i * i <= n; ++i) { if(n % i == 0) return false; } return true; } }

  21. PowerVector • High degree of coherency in PowerVector • Is not concerned with notification issues public class PowerVector { private Vector items_ = new Vector(); public PowerVector() { } public Object get(int index) { return items_.get(index); } public void add(Object o) { items_.add(o); } public void remove() { items_.remove(items_.size() - 1); } public int getSize() { return items_.size(); } }

  22. Client public class Client { private PowerVector vec_ = new PowerVector(); private RequestHandler chain_ = new RequestHandler(); public Client() { chain_.attach(new RequestHandler() { public boolean handle(Integer val) { vec_.add(val); return true; } }); chain_.attach(new EvenFilter()); chain_.attach(new PrimeFilter()); } public void run() { for(int i = 0; i < 25; ++i) chain_.invoke(new Integer(i)); System.out.println("Size=" + vec_.getSize()); for(int i = 0; i < 3; ++i) vec_.remove(); System.out.println("Size=" + vec_.getSize()); }

  23. Summary • The three patterns allow modeling of different situations • Obviously, they can be used together to get a combined effect • Command: • An invoker does not know who is the actual receiver • An invoker does not know which method should be called • Observer: • Several observers are all interested in a single object • Chain-of-Responsibility • Several handlers are all interested in a single request • The chain represents a single request • A handler does not know who is the actual invoker

More Related