Design Patterns A design pattern is a general solution to a particular class of problems, that can be reused. They are applicable not just to design. You can think of patterns as another level of abstraction. It is a solution that can be easily translated into code. Typically not built into the language. Design Patterns 1 48 Howard Cheng
Types of Design Patterns Creational: how an object can be created Structural: the way objects are connected with each other Behavioral: objects that handle particular types of actions within a program. Design Patterns 2 48 Howard Cheng
The Singleton Pattern Used to restrict one and only one instance of a class. They are preferred to global variables because of namespace pollution and lazy allocation. A class would use a static method to create an object if there is not already an instance, or return a reference to the single object. Disallow (copy) constructor and assignment operator. Allocate static object inside getinstance() function. Example usage: central manager (e.g. window manager), log file, Builder objects. Design Patterns 3 48 Howard Cheng
The Singleton Pattern Singleton static uniqueinstance: singletondata static Instance() SingletonOperation() GetSingletonData() return uniqueinstance Design Patterns 4 48 Howard Cheng
The Factory Pattern If you use polymorphism to create new classes, new types can be added without disturbing much existing code... except when you create the objects Solution: force the creation of objects to occur through a common factory. The factory method can be a virtual function in the base class. A separate factory class can also be created to create the appropriate objects given a parameter. Design Patterns 5 48 Howard Cheng
The Factory Pattern Framework Document Application CreateDocument() newdocument() Document* doc = CreateDocument(); // add doc to container Application MyDocument MyApplication CreateDocument() return new MyDocument() Design Patterns 6 48 Howard Cheng
The Abstract Factory Pattern Encapsulates a group of similar factories. The client creates a concrete implementation of abstract factory and use the abstract interface. The client does not know which object is created. Allows concrete classes to be changed without changing the client code. e.g. create a window in different windowing environment. Design Patterns 7 48 Howard Cheng
The Abstract Factory Pattern <<interface>> AbstractFactory CreateProductA() CreateProductB() Client AbstractProductA AbstractProductB ConcreteFactory1 CreateProductA() CreateProductB() ConcreteFactory2 CreateProductA() CreateProductB() ProductA1 ProductA2 ProductB1 ProductB2 Design Patterns 8 48 Howard Cheng
The Builder Pattern The builder pattern is used to build objects. A builder class tries to build an object one step at a time (through composition). A director class is responsible for managing the correct sequence of steps of object creation. For example: building a car from its parts. Design Patterns 9 48 Howard Cheng
The Builder Pattern RTFReader Parse() DocumentConverter ConvertParagraph( :char) ConvertFont( :Font) ConvertParagraph() while (t = get_next_token()) { switch(t.type) case CHAR: builder->convertcharacter(t.aschar) break case FONT: builder->convertfontchange(t.asfont) break case PARAGRAPH: builder->convertparagraph() } AsciiConverter AsciiDocument TexConverter TexDocument HtmlConverter HtmlDocument Design Patterns 10 48 Howard Cheng
The Prototype Pattern Sometimes we want to create objects based on a prototype object which is then cloned to produce new objects. Avoids subclasses of object creator (e.g. abstract factory). An abstract base class specifies a pure virtual clone() method. Useful when there are only a few different possible values for objects. This is kind of a polymorphic constructor. A factory method can be used in combination to create objects from prototypes from different classes. Design Patterns 11 48 Howard Cheng
The Prototype Pattern Client Operation() Prototype Clone() p = prototype->clone() ConcretePrototype1 Clone() ConcretePrototype2 Clone() Design Patterns 12 48 Howard Cheng
The Adapter Pattern The adapter pattern is a way to wraparound some classes to provide an interface expected by some other class. The adapter may also transform input/output data into the right forms. The target is how you want to use the class. The adaptee is the underlying class. e.g. string stream, stream iterator Design Patterns 13 48 Howard Cheng
The Adapter Pattern Client Target Request() Adaptee SpecificRequest() Adapter Request() SpecificRequest() Design Patterns 14 48 Howard Cheng
The Bridge Pattern This pattern is used to decouple an abstraction from its implementation, so that the two can vary independently. If only the class may vary, then inheritance is good enough. But if the behavior of the class may also vary, using inheritance may result in too many classes with duplicated code. For example, different Shapes that can be drawn differently depending on the graphical user interface. Design Patterns 15 48 Howard Cheng
The Bridge Pattern 3DShape Draw() Cube Prism Pyramid CubeDX CubeOGL PrismDX PrismOGL PyramidDX PyramidOGL DirectX OpenGL Design Patterns 16 48 Howard Cheng
The Bridge Pattern One inheritance tree is used for the classes. Another tree is used to handle the different implementation (behavior). The abstract base class has a reference (or owns) the abstract base of the implementation class. The right function is triggered automatically by polymorphism. Design Patterns 17 48 Howard Cheng
The Bridge Pattern 3DShape Draw() DrawLine() 3DImplementation Cube Prism Pyramid DXImplementation OGLImplementation DirectX OpenGL Design Patterns 18 48 Howard Cheng
The Composite Pattern Sometimes we want to perform the same command to a group of objects. These commands often can be applied to a single object as well. e.g. deleting a single message vs. deleting a group of message. It may be useful if a group of object can be treated in exactly the same way as a single instance of an object. The composite pattern use tree structures to represent part-whole hierarchies. A abstract base class is used to model each component, which can either be a leaf or a composite class. Each component supports an operation (e.g. delete). The client can invoke the operation from the component for the whole group. Design Patterns 19 48 Howard Cheng
The Composite Pattern Component Client Operation() Add(c:Component) Remove(c:Component) GetChild(i:int) child Leaf Operation() Composite Operation() for all c:child c->operation() Design Patterns 20 48 Howard Cheng
The Decorator Pattern Allows functionality of a class to be extended at runtime. A new decorator class wraps the original class. Decorator takes an object of original class in constructor. Decorator implements new functionalities, but must have the same interface as original class. Inheritance adds new behaviour at compile time. e.g. GUI: add scrollbars, borders, etc. to windows, adding access control to users. Design Patterns 21 48 Howard Cheng
The Decorator Pattern Component Operation() ConcreteComponent Decorator Operation() component->operation() ConcreteDecoratorA addedstate Operation() ConcreteDecoratorB Operation() AddedBehaviour() Decorator::Operation() AddedBehaviour() Design Patterns 22 48 Howard Cheng
The Façade Pattern Used to provide a simpler interface for a large body of code. Reduce dependencies of inner workings of a library. e.g. database, compiler, etc. Design Patterns 23 48 Howard Cheng
The Flyweight Pattern Often, an application needs to use a large number of similar objects. e.g. a drawing application may need to use a large number of Pen objects to specify how each object is to be drawn (e.g. colour, thickness, etc.). The states of these objects can often be shared (e.g. there may only be a few different colours). A flyweight is an object that is shared by many other objects to minimize memory usage. The state is divided into intrinsic state (the common part) and extrinsic state (the rest). e.g. intrinsic: pen colour, thickness, etc. extrinsic: endpoints of line A factory method creates a required flyweight object if it does not already exist, and return a reference to it. Design Patterns 24 48 Howard Cheng
The Flyweight Pattern FlyweightFactory getflyweight(key) Flyweight Operation(es:ExtrinsecState) State if(flyweight[key] exists) { return existing flyweight } else{ create new flyweight add it to pool return the new flyweight } Client ConcreteFlyweight is:intrinsecstate ConcreteUnsharedFlyweight as:allstate IntrinsecState ExtrinsecState Design Patterns 25 48 Howard Cheng
The Proxy Pattern A proxy is a class acting as an interface to something else. Can be used to encapsulate file, network, GUI, etc. One base class for common interface. One real implementation as subclass. One proxy implementation to delegate to the real implementation. Can be used to defer creation of objects until needed. e.g. smart pointers. Design Patterns 26 48 Howard Cheng
The Proxy Pattern Client Subject Request() RealSubject Request() Proxy Request() realsubject->request Design Patterns 27 48 Howard Cheng
The Chain of Responsibility Pattern A set of processing objects that describes what command objects it can handle, and how to pass off those it cannot handle. Allows the client to send a request to only one chain instead of a specific object decouples a request sender and receiver. The first processing object that can handle the command will do it. e.g. help button: the request is passed from the most limiting component (e.g. button) up the chain until one can handle it. Every class has a single responsibility. The chain can be constructed at run time. Design Patterns 28 48 Howard Cheng
The Chain of Responsibility Pattern HelpHandler handlehelp() handler handler->handlehelp() Application Widget Dialog Button handlehelp() showhelp() if(can handle) { showhelp(); }else{ handler->handlehelp(); } Design Patterns 29 48 Howard Cheng
The Command Pattern Command Objects are used to encapsulate actions and their parameters. Examples: PrintJob, TestRunner. The command class may have an execute() or run() method. Similar to function pointers, but can store extra parameters. Can collect command objects to execute them in sequence. Allows one to treat all commands in a similar way (execute(), undo(), getestimatedduration()). Example application: maintaining an undo list (each command class has an undo() method), specifying actions for menu items, queueing jobs. Design Patterns 30 48 Howard Cheng
The Command Pattern Application Menu MenuItem Command add(d:document) add(mi:menuitem) onclick() execute() onclick() { command->execute(); } Document open() close() cut() copy() pastecommand execute() execute() { document->paste(); } OpenCommand execute() execute() { name = askuser() doc = new Document(name); application->add(doc); doc->open(); } Design Patterns 31 48 Howard Cheng
The Interpreter Pattern Use a specialized computer language to solve a restricted class of problems. Have one class for each symbol in the language. It is easy to change and extend the grammar. e.g. calculator language, database query language (SQL), etc. e.g. every class can have a generate code function. Design Patterns 32 48 Howard Cheng
The Iterator Pattern It describes a way to access elements in any container in a sequential manner. The internal representation of the container is not exposed. This is implemented in STL containers. All containers can be accessed in a consistent manner. Design Patterns 33 48 Howard Cheng
The Iterator Pattern Container CreateIterator() Append(i:Item) Client Iterator First() Next() isdone() CurrentItem() List Vector ListIterator VectorIterator First() Next() isdone() CurrentItem() Design Patterns 34 48 Howard Cheng
The Mediator Pattern Provides a unified interface to a set of interfaces in a subsystem. Communication between objects is encapsulated with a mediator object. Lower coupling. Mediator: defines interface for communication between colleagues ConcreteMediator: implements the Mediator interface and coordinates communication. ConcreteColleague: communicates with other colleagues through its mediator. e.g. many components in a GUI dialog may have to interact with each other selecting one component may require an update of another component. Design Patterns 35 48 Howard Cheng
The Mediator Pattern EntryField RadioBox RadioBox ListBox RadioBox FontDialogDirector EntryField RadioBox ListBox Button vs. Button Design Patterns 36 48 Howard Cheng
The Memento Pattern This pattern provides the ability for an object to restore itself to a previous state. The originator is the object of interest. A caretaker wants to perform an operation on the originator, and asks it for a memento object first. The memento object can be used to restore the orignator s state. The memento object cannot be examined by anyone other than the originator. e.g. random number generator, finite state machine. Design Patterns 37 48 Howard Cheng
The Memento Pattern Originator SetMementor(Memento m) CreateMemento() state return new Memento(state) state = m->getstate() Memento GetState() SetState() state CareTaker Design Patterns 38 48 Howard Cheng
The Observer Pattern An object maintains a list of dependents and notifies them automatically of any state change. The notification is done by calling a method from the dependent. Each dependent is an observer, and should have an update() method. A subject allows each observer to attach and detach itself. The subject is responsible for notifying the observers when a change has occurred. e.g. GUI views: when the underlying data has changed, the GUI has to be informed to be redrawn. Design Patterns 39 48 Howard Cheng
The Observer Pattern Subject Attach(o:Observer) Detach(o:Observer) Notify() <<interface>> Observer Update() forall o in observer o->update() ConcreteSubject subjectstate GetState() SetState() subject#1 ConcreteObserver observerstate Update() observerstate = subject->getstate() return subjectstate Design Patterns 40 48 Howard Cheng
The State Pattern The intent is for the class to choose one of the real implementations as appropriate at run time. The choice can change at run time. e.g. Dead/alive for players, drawing tool (different behaviour for mouse click for different tools). Move logic from code into classes. Design Patterns 41 48 Howard Cheng
The State Pattern TCPConnection Open() Close() Acknowledge() TCPState Open() Close() Acknowledge() state->open() TCPEstablished TCPListen TCPClosed Design Patterns 42 48 Howard Cheng
The Strategy/Policy Pattern Sometimes it is useful to dynamically swap the algorithms used in an application. The strategy pattern encapsulates each algorithm as an object and make them interchangeable. Use a polymorphic base class and inherit each algorithm as a subclass. A wrapper context class is used to hold a pointer to the base class, and provides a way to set a particular algorithm. Design Patterns 43 48 Howard Cheng
The Strategy Pattern Sorter MethodWithSort() Sort Sort() sort->sort() QuickSort HeapSort NaiveSort Design Patterns 44 48 Howard Cheng
The Template Method Pattern Useful for modelling a related set of algorithms. Each algorithm is encapsulated as an abstract base class. The steps of the algorithm are implemented as virtual functions. The abstract base class implements the algorithms by calling the virtual functions. Specific variation of algorithms are achieved by deriving from the abstract class and overriding the virtual functions. e.g. two-player game: initialize game, deciding whose turn it is, make a move, deciding end of game, deciding winner. Design Patterns 45 48 Howard Cheng
The Template Method Pattern Document Read() Application CreateDocument() CanOpenDocument() InitializeOpenDocument() OpenDocument() MyDocument Read() MyApplication CanOpenDocument() InitializeOpenDocument() CreateDocument() Design Patterns 46 48 Howard Cheng
The Visitor Pattern Separates an algorithm from an object structure upon which it operates. Each element class has an accept() method which takes a visitor object as a parameter. Visitor is an interface with a visit() method for each element class. The accept() method calls back visit(). Different visitor classes are used to perform different operations. New functionality can be added by defining new visitor classes without changing object structure. Design Patterns 47 48 Howard Cheng
The Visitor Pattern Visitor Node TypeCheck() GenerateCode() Write() TypeCheckingVisitor WritingVisitor VariableReferenceNode AssignementNode OperationNode CodeGeneratingVisitor VisitAssignmentNode(n:AssignmentNode) VisitVariableReferenceNode(n:VariableReferenceNode) VisitOperationNode(n:OperationNode) Program Node AcceptVisitor(v:Visitor) AssignementNode AcceptVisitor(v:Visitor) VariableReferenceNode AcceptVisitor(v:Visitor) v->visitassignementnode(this) v->visitreferencenode(this) Design Patterns 48 48 Howard Cheng