2
Design Patterns Outline
What is a pattern? The Design Patterns Book One example pattern: Singleton Patterns versus Idioms
Complex algorithms and the Strategy patternCreating new objects: Factories Factory method Abstract factory
Wrapping with Facade objectsRemote access with ProxyStructuring objects with CompositeAdding behavior with Decorator
3
What is a pattern?
A pattern is a solution to a problem in a contextThe problem and context come from some domain (software development, project management, …) The problem and context
contain some “unresolved forces” that need to be addressed.
The solution is a proposed way to resolve the problem
Name: Information Expert
Problem: How to decide which class or object to assign responsibilities to?
Context: A responsibility usually requires some information or data for its fulfillment – information about other objects, an object’s own state, the world around an object, and so on.
Solution: Assign a responsibility to the class that has the information needed to fulfill it. (from Applying UML and Patterns, third edition, Craig Larman)
4
What is a pattern?
Patterns are used to capture knowledge and experience – for example, what to think about when making design choices
Not a cookbook
Each pattern might trigger others
Name: Loose Interfaces
Problem: To avoid development bottlenecks, we need to be able to limit the effect that one team’s work will have on another.
Context: Interfaces need to be somewhat flexible if the teams are working quickly. Requirements may be changing rapidly, and it may be difficult to communicate between geographically distributed subteams.
Solution: Limit the number of explicit, static interfaces. Define larger-grained interfaces that allow developers to code against interfaces defined early, but that do not overly constrain functionality. Consider using the Hierarchy of Factories pattern.(from Organizational Patterns of Agile Software Development, Coplien and Harrison)
5
Software patterns
The first “Object Oriented Design Patterns” are found in the book Design Patterns by Erich Gamma, Richard
Helm, Ralph Johnson, and John Vlissides (known as “Gang of 4” or “GOF”)
23 patterns: three categories (Creational, Structural, Behavioral)
Problems: control the construction of objects create organized collections of objects divide responsibilities among objects for
better encapsulation and easier modification Examples in C++ and Smalltalk The patterns also apply to other languages
(Java, Visual Basic, Perl)
6
Singleton Pattern
Name: Singleton
Problem: We need to restrict the creation of new objects for a particular class: only one instance.
Context: Other objects in the design need a single point of access to use the object.
Solution: Define a “static member function” within the class that returns a pointer (or reference) to the Singleton object. The static member function will create the object the first time it is called. All constructors are made private to prevent other objects from being created.
7
More about Singleton
Simple version of Singleton (in C++, without multi-thread support):
if (instance == 0) { instance = new MySingletonClass();}return instance;
MySingletonClass– instance : MySingletonClass *other attributes …+ getInstance() : MySingletonClass *– MySingletonClass()other operations …
• Access the Singleton like this: MySingletonClass::instance()• Different implementations of the Singleton pattern for Java,
multithreaded support, allocation in special memory, and so on.
underline meansstatic data member
8
Patterns and Idioms
What have we done? We have used a “design trick” that solves a specific problem
Some standard design tricks are called “idioms” they tend to be small, tricky, and language specific example: virtual destructors in C++ example: anonymous inner classes in Java
How are patterns different from idioms? Patterns are more about design Singleton is useful in Java, Smalltalk, Visual Basic, Perl, … different “realizations” of patterns in different languages
9
Patterns in the Design Patterns book
23 Design Patterns: three categories
Creational Structural Behavioral
Abstract Factory Adapter Chain of Responsibility
Observer
Builder Bridge Command State
Factory Method Composite Interpreter Strategy
Prototype Decorator Iterator Template Method
Singleton Facade Mediator Visitor
Flyweight Memento
Proxy
10
Sources of information
So, you want to learn how to use these design patterns to make your OO designs better
Where to look to learn more: the book A Learning Guide to Design Patterns
(http://www.industriallogic.com/papers/learning.html) Pattern Stories Wiki (http://wiki.cs.uiuc.edu/PatternStories) http://c2.com/cgi/wiki?DesignPatterns other books:
Pattern-Oriented Software Architecture by Frank Buschmann et. al. Design Patterns Java Workbook by Steven John Metsker Refactoring to Patterns by Joshua Kerievsky Design Patterns Explained by Alan Shalloway and James R. Trott
11
Why learn the Design Patterns?
Your own designs will improve borrowing well-tested ideas pattern descriptions contain some analysis of tradeoffs
You will be able to describe complex design ideas to others assuming that they also know the same patterns
You can use patterns to “refactor” existing code refactoring is improving the structure of existing code without
adding new functionality some techniques for transforming and adapting legacy code are
based on design patterns
12
Strategy Pattern
Problem: An application needs to use a family of similar algorithms the selection of which algorithm depends on the client making the
request or some characteristics in the data
Context: Two possible situations: you have a group of classes that contain the same data, but they
have different behavior (functions); or you have a class that defines many behaviors, and these
behaviors appear as multiple conditional statements in the operations of the class
Solution: Define a family of algorithms, encapsulate each one, and make them interchangeable there will be a family of classes, one per algorithm variation
13
Example of Strategy
Internet-based business When a customer accesses the
home page, you want to present a few products that the customer might be interested in
Web presentation program uses one or more “recommendation engines”
commercial off the shelf software uses customer survey information
or previous purchase history to make a recommendation
Might use multiple engines Might also want to highlight special
sale items
Customer
getAdvisor()getRecommended()
GroupAdvisorrecommend(Customer)
ItemAdvisorrecommend(Customer)
PromotionAdvisorrecommend(Customer)
Advisor<<abstract>>
recommend(Customer) :ProductSet
call one of therecommendation
engines
call a promotion-based selector
14
Strategy consequences
Strategy implements a flexible algorithm Separate a varying algorithm from the rest of the design Use a class hierarchy and virtual functions to allow
application code to select the correct algorithm at execution time
It’s easy to add new algorithms – assuming the interface is the same
But there are tradeoffs: Complex coupling between context and strategy Some concrete strategy classes might not use
everything that is supplied by the context
15
More patterns examples
Polymorphic creation with Factories: an application might need to make new objects from
several related classes
Defining clean interfaces with Facade: wrapper classes – might even wrap non-OO code
Remote access with Proxy
Building complex structures with Composite
Adding variations with Decorator
16
Factory Method Pattern
Problem: An application needs to create an object the application isn’t sure which type of object to create
Context: the application knows which “family” of classes the
created object will belong to: the object to be created will always support a specific abstract interface
Solution: Define a factory method in the object creator’s base class, define subclasses that each create the correct type of object for a specific situation
17
Creation methods
To lead up to an example of a Factory Method – first think about creation methods in many OO languages (C++,
Java), objects are created by constructor functions
if you want a specific kind of object, you can use a normal declaration in C++, or call the new operator in C++ or Java
OR, you can move the creation of the object to a separate function (a creation method)
class Myclass {public: Myclass(); // default constructor Myclass(int maxcalls); Myclass(std::string config_name); …};
int main() { Myclass m1, m2(100); Myclass *mptr1 = new Myclass; Myclass *mptr2 = make_object(50);}
Myclass *make_object(int n) { return new Myclass(n);}
18
Creation methods
Creation methods are a good supplement to constructors It is possible to give the creation method a name that indicates its
purpose; the name of a constructor is always the name of the class A creation method might be defined to both “construct” an object
plus associate a strategy object with the new object A creation method might use another pattern as a construction
shortcut: such as the Prototype pattern (fill in an object from an existing object)
Where to define a creation method? Three options Define the creation method as a static member function of the
class being created In a special Factory class Within the class that uses the constructed class
19
Multiple related creation methods
You might be in a situation where you need multiple creation methods in one situation, you want to create an InternalCall in another situation, you want to create a RegularCall and in yet another situation, you want to create an InternationalCall AND, all three classes are part of the same hierarchy
Call
RegularCallInternalCall InternationalCall
Call *make_int_call(string num) { return new InternalCall(num);}Call *make_reg_call(string num) { return new RegularCall(num);}Note: no design patterns happening yet…
We’ll get there is another slide or two…
20
Why are dynamic objects important?
It is natural for object oriented designs to have dynamic objects: heterogeneous collections (a collection containing a mixture of similar objects) objects with a short lifetime (tasks, events, messages, dialogs)
ChannelCard <<abstract>>
CC_model2CC_model1 CC_model3
CardShelf
cards : ChannelCard *[5]
shelf_status : STATUS*
This array points to all ofthe ChannelCard objects
for the current configurationif (get_shelf_signature_signal(i) == MODEL1) { cards[i] = new CC_model1();}
Example: An OA&M subsystem may need to keep information about number of different physical objects
21
InternatFaxSender
create_call_for_faxing
Factory Method
In Factory Method – the responsibility for creating an object will be assigned to the class that uses it…
We need to look at how a class hierarchy might be used in an application: For example, a FaxSender class might have a fax_it() member function which needs
to create a Call object The type of Call is usually a RegularCall, but subclasses (such as an
InternatFaxSender) are allowed to override the creation
FaxSendermycall : Call*fax_itcreate_call_for_faxing
fax_it() calls this->create_call_for_faxing()
an extension class
virtual Call *create_call_for_faxing(string num) { return new RegularCall(num); }
virtual Call *create_call_for_faxing(string num) { return new InternationalCall(num); }
Note: the fax_it() function works the
same way for a FaxSender or an
InternatFaxSender
22
Factory Method
A Factory Method is a creation method in any base class within an application The “design trick” is: subclasses are permitted to
create any compatible object The base class Factory Method almost always returns a
“pointer to a base class” (or a “pointer to an abstract interface”)
Subclasses that redefine the Factory Method will still return a pointer to base class, but they might create a different kind of concrete object
23
Facade Pattern
Problem: The application needs a simple interface to a complex subsystem the subsystem might have been written by someone else
Context: it is important to control the dependencies between the application
and the complex subsystem – you want to reduce the effort to maintain the system
Solution: Define a single Facade class: the Facade class has knowledge of the internal details of the subsystem, but the Facade class provides a simple to use interface for the application each Facade public function might call many subsystem operations
24
Facade diagram
A Facade class wraps a bunch of operations on other classes (or a bunch of legacy code operations) into a convenient package
application Facade classpointers to other dataobjects within asubsystemget_val1()build_trans2()do_trans3()commit_trans4()
application callssome of the Facade
class operations
scanner
databaseinterface
parser
formatterthe Facade accessessome of the internals
of a complex subsystem toimplement its operations
25
Planning a Facade
Part of the OO design process: create a simplified model of the classes in the overall system using CRC cards (informal technique using index cards, one card
per class) using UML Class Diagrams
Look for a group of classes that collaborate closely together: call them a “subsystem”
Try to “put the subsystem behind a wall” – define a single interface class that defines an API for the subsystem
26
Proxy example
A Proxy object is a “stand-in” for an object that might be: located on another machine (example: CORBA objects, Java RMI) or it might be large and complicated, so you want to defer building it or it might require a special access method (to check the users’
permissions)
client application
network
ORB (server)
CORBAIDL stubs
IDL skeletons
InterfaceRepository
ObjectImplementations
CORBA example
requests responses
Stub objects have fullpublic interface, but no data.They just push a message
over to the server.
Generatedby a tool
Developersfill in details
27
Proxy pattern
Problem: The application needs to operate on a distant objectContext: Need a placeholder for an object if the actual object is far away (on another computer or on a disk),
the placeholder should be in the local address space
Solution: Define a Proxy class: this class will have the same public interface as the real class, and when a Proxy operation is called, the internals of a Proxy object will arrange for the same function to be called on a real object Proxy might send interprocess or intermachine messages Proxy might resurrect an object that has been written to disk Proxy might acquire special permissions to access a protected real
object
28
How to tell the difference?
How can I tell which one I am using? Facade or Proxy? Both patterns are separating the implementation details from an
abstract interface But the intent is different for each pattern
Facade: the application wants to use services of an entire subsystem or package (usually tens or hundreds of objects in the subsystem)Facade is also a common way to interface with non-OO modulesProxy provides convenient access to an object – the object might be on disk, in another process, on another computer
29
Multiple related creation classes
The Abstract Factory pattern: define multiple parallel creation classes whenever you define a new subclass of Call, define a new creation class
Call
RegularCall
InternalCall
InternationalCallCall *IntCallFactory::make_call(string num) { return new InternalCall(num);}
CallFactory
RegCallFactory
IntCallFactory
InternatCallFactory
Call *RegCallFactory::make_call(string num) { return new RegularCall(num);}
30
Composite Pattern
From Design Patterns: “Graphics applications like editors let users build complex diagrams out of simple components” how to represent a complex diagram? diagram is a combination of primitive items (lines, boxes, text objects) in addition, a group of primitive items (a “picture”) could be represented
as a single object and a picture might contain other pictures
Line Line Line Line
Picture Box
Picturepicture four lines and a box
31
Composite class diagram
Here is one proposed design:
Line
Draw
Box
Draw
Text
Draw
Picture
DrawAdd(Graphic *g)Remove(Graphic *g)GetChild(int)
Graphic
DrawAdd(Graphic *g)Remove(Graphic *g)GetChild(int)
this supports the recursive containment
for all g in children g->Draw();
children
32
General diagram for Composite
In general, the Composite is
Leaf
Operation()
Composite
Operation()Add(Component *g)Remove(Component *g)GetChild(int)
Component
Operation()Add(Component *g)Remove(Component *g)GetChild(int)
for all g in children g->Operation();
children
several different kinds of Leaf classes can be
subclasses of Component
33
Consequences
Applications treat composite and leaf objects uniformly – in the example, the Draw() function on a composite will recursively draw the lower level objects
Easy to add new leaf classes within the framework
34
Decorator Pattern
Problem: You want to add operations to specific objects.Context: There may be lots of different combinations of data and operations
needed. Defining new subclasses for each combination would be too
tedious. You may also want to add data and behavior dynamically. You don’t want to affect ordinary objects.
Solution: Define one or more Decorator classes that define a set of new operations. Then attach a Decorator object to the object whose operations you want to augment. a Decorator is very similar to an Adapter
35
Decorator Pattern example
Suppose Call is an abstract interface, and RegularCall is the most commonly created concrete subclass
Instead of subclassing RegularCall to add new functions, we can “decorate” RegularCall instead
Call <<abstract>>
get_idset_uptear_down
RegularCall
call_id
get_idset_uptear_down
CallDecorator<<abstract>>
Call *component
get_idset_uptear_down
d1 : PictureMailCallDecorator
component
d2 : EmailviewCallDecorator
component
d3 : WiretapCallDecorator
component
call1 : RegularCall
call_id = “3517711”
concrete Decoratorclasses are derived
from this class
WiretapCallDecorator
set_up
EmailviewCallDecorator
set_up
36
Decorator diagram
This pattern permits the definition of one or more Concrete Decorator classes these Decorator classes implement the entire public interface of the “Decoratee” implemented by delegation: abstract Decorator has forwarding functions; concrete Decorator
subclasses can overrideComponent <<abstract>>
Operation()
Decorator <<abstract>>
Operation()
ConcreteComponent
… attributes …
Operation()
// delegate to ConcreteComponent component->Operation();
ConcreteDecoratorA
… extra attributes …
Operation()Added_operation()
this is the “Decoratee”
(no real restrictions on the structure or
behavior)
component
component->Operation(); this->Added_operation();
37
Designing the Decorator
Decorator avoids subclassing the Decoratee class the design just gets lots of small classes that optionally add
nuggets of functionality to an existing class since each Decorator implements the full set of behaviors of the
base Component class, a pointer to a Decorator can be passed into any function that expects the base Component
If you start your design with just a Concrete Component, you have to do some refactoring of the existing application to change “concrete” to “abstract” wherever it makes sense this is a good design practice anyway and it makes way for decorated objects being applicable anywhere
a plain object is OK
38
Consequences
A Decorator is a transparent enclosure – any member function call will be forwarded to the component class
If a component class has a large public interface (more than 10 or 12 public member functions), it can be a lot of work to define a Decorator because each Decorator must at a minimum define the same public
interface as the component class
Decorator add new behavior in little objects that cling to the main domain classes don’t want to obscure the main lines of the design and the most
frequently executed scenarios
39
Summary
Design Patterns: an important set of object oriented design concepts these patterns are useful in many applications every pattern has a documented set of “Consequences”
Many more design patterns exist: http://hillside.net/patterns/onlinepatterncatalog.htm http://www.martinfowler.com/articles/enterprisePatterns.html http://java.sun.com/blueprints/corej2eepatterns