![Page 1: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/1.jpg)
1
Pattern GamesPattern Games
CS 236700: Software Design
Winter 2004-2005/T9
![Page 2: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/2.jpg)
2
Overview of the programsOverview 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
![Page 3: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/3.jpg)
3
Participating classesParticipating 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, …
![Page 4: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/4.jpg)
4
Skeleton of class PowerVector 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); }}
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); }}
![Page 5: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/5.jpg)
5
Skeleton of class Client 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(); }}
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(); }}
![Page 6: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/6.jpg)
6
11stst program 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
![Page 7: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/7.jpg)
7
Command: intentCommand: intent
Encapsulate a request as an object, thereby letting you
parameterize clients with different requests, queue or log requests,
and support undoable operations.
Encapsulate a request as an object, thereby letting you
parameterize clients with different requests, queue or log requests,
and support undoable operations.
![Page 8: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/8.jpg)
8
SizeKeeperSizeKeeper
public class SizeKeeper { private int size_ = 0; public void incSize(int diff) { size_ += diff; } public int getSize() { return size_; }}
public class SizeKeeper { private int size_ = 0; public void incSize(int diff) { size_ += diff; } public int getSize() { return size_; }}
![Page 9: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/9.jpg)
9
ICommand, SizeCommandICommand, 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_); } }
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_); } }
![Page 10: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/10.jpg)
10
PowerVectorPowerVector
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 }}
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 }}
![Page 11: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/11.jpg)
11
ClientClient
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}
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}
![Page 12: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/12.jpg)
12
22ndnd program 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
![Page 13: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/13.jpg)
13
Observer: intentObserver: intent
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are
notified and updated automatically.
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are
notified and updated automatically.
![Page 14: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/14.jpg)
14
IObserver, SizeKeeperIObserver, 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_; } }
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_; } }
![Page 15: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/15.jpg)
15
PowerVectorPowerVector
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 }
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 }
![Page 16: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/16.jpg)
16
ClientClient
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}
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}
![Page 17: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/17.jpg)
17
33rdrd program 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
![Page 18: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/18.jpg)
18
Chain-of-Reponsibility: intentChain-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.
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.
![Page 19: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/19.jpg)
19
RequestHandlerRequestHandler
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; } }
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; } }
![Page 20: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/20.jpg)
20
EvenFilter, PrimeFilterEvenFilter, 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; }}
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; }}
![Page 21: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/21.jpg)
21
PowerVectorPowerVector
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(); } }
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(); } }
High degree of coherency in PowerVector
Is not concerned with notification issues
![Page 22: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/22.jpg)
22
ClientClient
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()); }
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()); }
![Page 23: 1 Pattern Games CS 236700: Software Design Winter 2004-2005/T9](https://reader035.vdocument.in/reader035/viewer/2022062516/56649d415503460f94a1b846/html5/thumbnails/23.jpg)
23
SummarySummary 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