Date post: | 18-Jan-2018 |
Category: |
Documents |
Upload: | nickolas-newman |
View: | 218 times |
Download: | 0 times |
CSE 332: Design Patterns (Part II)
Last Time: Part I, Familiar Design Patterns• We’ve looked at patterns related to course material
– Singleton: share a class instance across multiple uses– Command: package up a function as an object– Iterator: access elements sequentially no matter how stored– Adapter: converts interface you get into one you want– Factory method: creates a related type polymorphically
• Now, let’s look at some other important patterns (Part II)– Bridge: allow interface, implementation to vary separately– Chain of responsibility: give request to chain of handlers– Composite: common interface to composite/simple objects– Interpreter: build a representation for a simple language– Observer: tell registered observers when state changes– Strategy/template method: vary steps/all of an algorithm– Proxy: forward requests from placeholder to another object– Memento: package up object state without violating encapsulation– Visitor: allow various operations on fixed set of objects (2-way dispatch)
CSE 332: Design Patterns (Part II)
Bridge Pattern• Problem
– Want to decouple an abstraction from its implementation, allowing them to vary separately
• Context– Want to change implementation details at run-time without
impact to clients• Solution
– Use delegation from an interface class to an implementation class
– Commonly used with templates• Consequences
– Can change (or add) interface without re-implementing– Can change implementation but not impact interface clients
CSE 332: Design Patterns (Part II)
Chain of Responsibility Pattern• Problem
– May not know which objects can handle a request, or may add complexity to specify exactly which ones
• Context– More than one object can handle a request– Want to pass requests to a group of objects– Handler objects can be specified dynamically
• Solution– Chain handler objects, pass requests along the chain until
one (variation: multiple) object handles it• Consequences
– Can hand request to a chain without knowing its members– Can tack on a “no one handled request” notifier at end
CSE 332: Design Patterns (Part II)
Chain of Responsibility Structure
• Handler abstract base class provides interface• Handler ABC also links handlers together• Concrete handlers implement code
– To decide whether or not to handle a message– To handle the message itself– To decide whether to consume the message or pass it along
after handling it
Handler
ConcreteHandler
method () = 0;
method ();
successor
. . .
CSE 332: Design Patterns (Part II)
Composite Pattern• Problem
– Distinguishing between composite and simple objects makes applications more complex
• Context– Want to represent whole-part hierarchies– Want to hide differences between composite and simple objects from
clients
• Solution– Encapsulate composite and simple objects behind a common
interface
• Consequences– Can treat objects consistently as though they were simple– Can treat particular composites in specialized ways
• Example– Directories contain file system elements (files and directories)
CSE 332: Design Patterns (Part II)
Composite Pattern Structure Diagram
• Component class role gives a consistent interface– For example, file system elements can be listed with ls in Linux
• Leaf class role is for components without further sub-structure– For example files in Linux
• Composite class role is for components with multiple parts– For example, Linux directories that contain files and other directories
Leaf
method ();
Component
Composite
method () = 0;
method ();
children
1
n
CSE 332: Design Patterns (Part II)
Interpreter Pattern• Problem
– Simple languages can be useful but need an interpreter– Don’t want to write a complex interpreter, e.g., Lex/YACC
• Context– Grammar is simple, and simplicity more important than
efficiency• Solution
– Represent an interpreter by designing objects for each expression/sub-expression type
• Consequences– Can write expressions in simple language instead of C++– Helps simplify some programming tasks like parsing inputs
CSE 332: Design Patterns (Part II)
Interpreter Pattern Structure Diagram
• Expression abstract base class provides interface• SubExpression combines child expressions• TerminalExpression has no children
Expression
SubExpression
value () = 0;
value ();
childrenk
1TerminalExpression
value ();
CSE 332: Design Patterns (Part II)
Observer Pattern• Problem
– Need to update multiple objects when the state of one object changes
• Context– Multiple objects depend on the state of one object– Set of dependent objects may change at run-time
• Solution– Allow dependent objects to register with object of interest, notify
them of updates when state changes• Consequences
– When observed object changes others are notified– Useful for user interface programming, other applications
CSE 332: Design Patterns (Part II)
Observer Pattern Structure Diagram
• Each subject may have multiple observers• Each concrete observer has a concrete subject• Observers call attach and detach on subject
– To register/deregister interest in knowing when it changes• A concrete observer calls get and set methods on a
concrete subject
Subjectattach (); detach ();notify ();Observer *observers_;
ConcreteSubject
get (); set ();
Observer
ConcreteObserver
update () = 0;
update ();
1n
11
CSE 332: Design Patterns (Part II)
Observer Pattern Collaboration Diagram
ConcreteObserverB
notify ();
set ();
update ();get ();
update ();get ();
attach ();
attach ();
ConcreteSubject ConcreteObserverA
CSE 332: Design Patterns (Part II)
Strategy Pattern• Problem
– You want to plug a family of algorithms into and out of a program, interchangeably
• Context– Must have a consistent
interface (used by program)• Solution
– Encapsulate algorithms as different classes (or templates)
– Provide polymorphic interface that each class implements
• Consequences– Program need not change
when new strategies are added
Calculatorpush()=0;pop()=0;
Bounded_Calculatorpush();pop();
Unbounded_Calculatorpush();pop();
CSE 332: Design Patterns (Part II)
“Template Method” Pattern• Problem (besides its name ;-)
– You want to plug in and out individual steps of an algorithm
• Context– You have a fixed algorithm structure
within which individual steps may vary• Solution
– Define a fixed base class function that calls virtual “hook” functions which derived classes override
• Consequences– Algorithm is parameterized by behavior
of the virtual hook functions• Examples we’ve seen
– Generic programming version is provided by greater, less functors in the STL (e.g., with sort algorithm)
Encyclopedialook_up ();find()=0;print()=0;
Close_Match_Encyclopediafind();print();
Exact_Match_Encyclopediafind();print();
Caveat: the name can beconfusing – the pattern isnot about C++ templates
CSE 332: Design Patterns (Part II)
Using Strategy vs. Template Method
• Use the Strategy pattern when you want to plug in and out entire algorithms– E.g., using different implementation classes for sorting– Need to ensure polymorphism works correctly– Often implies having an abstract base class
• Use the Template Method pattern when you want to plug in and out individual steps of an algorithm– E.g., using different implementations of steps in an
algorithm– Watch out for “proliferation of classes” problem: Strategy
may be a better choice to provide all combinations of steps
CSE 332: Design Patterns (Part II)
Proxy Pattern• Problem
– Need to access an object but may not have access (or may need to defer cost of access) until just before use
• Context– Client may need interface to target object initially
• E.g., in order to compile– Implementation of target object may be created later
• May be on a remote machine, etc.
• Solution– Provide a placeholder with same interface as the target
object, which forwards requests to equivalent methods• Consequences
– Extreme decoupling of proxy and target– For example, they can even be on different machines
CSE 332: Design Patterns (Part II)
Proxy Pattern Structure Diagram
• Proxy “stands in” for target object• Proxy exhibits same interface as target object
– Forwards method invocations it receives to the target object
TargetObject
method ();
Interface
Proxy
method () = 0;
method ();
11
CSE 332: Design Patterns (Part II)
Memento Pattern• Problem
– Want to externalize state of an object without violating encapsulation
• Context– A snapshot of object state is needed– Providing a state interface would violate encapsulation
• Solution– Create a memento class with methods to get, set state– Provide an opaque representation of state itself
• Consequences– Can use memento to send object state over a socket, save it in
a file, put it into an undo stack, etc.
CSE 332: Design Patterns (Part II)
Visitor Pattern• Problem
– Operations on collections of objects may not apply to all objects, or apply differently to different objects
• Context– Object interfaces are fixed and diverse– Need to allow new operations, without coupling
• Solution– Represent operations to be performed as visitors, with the
interface of every visitor representing the different kinds of objects
• Consequences– Can add new operations without changing objects– Visitors can traverse lists, trees, graphs, etc. of objects
CSE 332: Design Patterns (Part II)
Visitor Pattern Structure Diagram
• Different elements have different concrete interfaces• Element abstract base class adds accept interface• “Double handshake” between visitor, element
– Visitor calls accept on an element– Element calls back to appropriate method (visitA or visitB)
• This lets visitor tailor its actions to concrete elements
Elementaccept () = 0;
ElementA
accept (); A_method ();
Visitor
ConcreteVisitor
visitA () = 0;visitB () = 0;
visitA ();visitB ();
ElementB
accept (); B_method ();
CSE 332: Design Patterns (Part II)
Visitor Pattern Collaboration Diagram
A_method ();
visitA ();
accept ();
ElementB ConcreteVisitorElementA
B_method ();
visitB ();
accept ();
CSE 332: Design Patterns (Part II)
Summary• We’ve looked at quite a few patterns
– Singleton: share a class instance across multiple uses– Command: package up a function as an object– Iterator: access elements sequentially no matter how stored– Adapter: converts interface you get into one you want– Factory method: creates a related type polymorphically– Bridge: allow interface, implementation to vary separately– Chain of responsibility: give request to chain of handlers– Composite: common interface to composite/simple objects– Interpreter: build a representation for a simple language– Observer: tell registered observers when state changes– Strategy/template method: vary steps/all of an algorithm– Proxy: forward requests from placeholder to another object– Memento: package up object state without violating encapsulation– Visitor: allow various operations on fixed set of objects (2-way dispatch)
• Think of these as a “design vocabulary” that you can use• CSE 432 will use these throughout next semester
– In iterative refinement of project designs and implementations