- In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation.
- The basic form of object creation could result in design problems or added complexity to the design.
- Creational design patterns solve this problem by somehow controlling this object creation.
- Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
- A hierarchy that encapsulates: many possible "platforms", and the construction of a suite of "products".
- The
new
operator considered harmful. - The three statements above imply the following:
- Each product has multiple styles.
- Products with different styles should be produced in separate factories tailored to their specific styles.
- For instance, consider products A and B, each available in styles X and Y.
- To manufacture these four variations, two factories are needed: Factory X and Factory Y.
- Factory X produces products A and B with style X.
- Factory Y produces products A and B with style Y.
- README.
- Code.
- Separate the construction of a complex object from its representation so that the same construction process can create different representations.
- Parse a complex representation, create one of several targets.
- The two statements above imply the following:
- Each product consists of several components.
- Different arguments are passed to these components to create distinct products.
- Each builder is responsible for a single product and determines the specific arguments passed to the components.
- Directors only need to call the appropriate builder to produce the required product.
- README.
- Code.
- Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
- Defining a
virtual
constructor. - The
new
operator considered harmful. - The three statements above imply the following:
- There are multiple products.
- A single factory can produce all these products.
- For instance, consider products A and B.
- To manufacture their four variations, only one factory is required.
- The factory is capable of producing both products A and B.
- README.
- Code.
- Object pooling can offer a significant performance boost.
- It is most effective in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high, and the number of instantiations in use at any one time is low.
- The two statements above imply the following:
- A resource is reused multiple times.
- An object with a list as a member is created to manage the resource.
- When a resource is requested, the object checks whether an available
resource exists:
- If one exists, it is returned.
- Otherwise, a new resource is created and returned.
- README.
- Code.
- Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
- Co-opt one instance of a class for use as a breeder of all future instances.
- The
new
operator considered harmful. - The three statements above imply the following:
- A factory contains many prototype products that have already been created.
- When a product is needed, the factory calls its
clone
method to produce a copy.
- README.
- Code.
- Ensure a class has only one instance, and provide a global point of access to it.
- Encapsulated "just-in-time initialization" or "initialization on first use".
- The two statements above imply the following:
- A class provides one method to instantiate and access itself within itself.
- The method and its instance are commonly
static
in C++. - The class is designed to prevent copying.
- README.
- Code.
- In Software Engineering, Structural Design Patterns are Design Patterns that ease the design by identifying a simple way to realize relationships between entities.
- Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
- Wrap an existing class with a new interface.
- Impedance match an old component to a new system.
- The three statements above imply two meanings as follows:
- Class Adapter (Inheritance-based):
- Create three classes:
Target
,Adaptee
, andAdapter
. - The
Adapter
class inherits from bothTarget
andAdaptee
. - The
Target
class only provides purevirtual
methods. - The
Adaptee
class provides all access methods. - The
Adapter
class implements all purevirtual
methods of theTarget
class, and these implementations call the methods of theAdaptee
class. - The client only needs to create a
Target
pointer to an instance of theAdapter
class and call its methods.
- Create three classes:
- Object Adapter (Composition-based):
- Create three classes:
Target
,Adaptee
, andAdapter
. - The
Adapter
class inherits from theTarget
class. - The
Target
class only provides purevirtual
methods. - The
Adaptee
class provides all access methods. - The
Adapter
class creates and manages anAdaptee
pointer to anAdaptee
instance and implements all purevirtual
methods of theTarget
class. These implementations call the methods of theAdaptee
class. - The client only needs to create a
Target
pointer to an instance of theAdapter
class and call its methods.
- Create three classes:
- Class Adapter (Inheritance-based):
- README.
- Inheritance-based Code.
- Composition-based Code.
- Decouple an abstraction from its implementation so that the two can vary independently.
- Publish interface in an inheritance hierarchy, and bury implementation in its own inheritance hierarchy.
- Beyond encapsulation, to insulation.
- The three statements above imply two meanings as follows:
- Create two interfaces:
Implementor
andAbstraction
. - Both
Implementor
andAbstraction
only provide purevirtual
methods. - Subclasses of
Abstraction
are associated withImplementor
, but both can vary independently. - Use
Abstraction
objects to accessImplementor
objects. - For example:
- Create two classes,
ConcreteImplementorA
andConcreteImplementorB
, inheriting fromImplementor
. - Create a class,
RefinedAbstraction
, inheriting fromAbstraction
. RefinedAbstraction
stores anImplementor
pointer to an instance of a subclass ofImplementor
. It implements all purevirtual
methods to access this object.- The client only needs to:
- Create an
Implementor
pointer to a specific instance of a subclass ofImplementor
. - Use it to construct an
Abstraction
pointer to aRefinedAbstraction
instance. - Call methods of the
Abstraction
interface.
- Create an
- Create two classes,
- Create two interfaces:
- README.
- Code.
- Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
- Recursive composition.
- "Directories contain entries, each of which could be a directory."
- 1-to-many "has a" up the "is a" hierarchy.
- The four statements above imply the following:
- Use a subclass to manage and access other subclasses.
- There are at least three classes:
Component
,Composite
, andLeaf
. Component
is an abstract class that provides purevirtual
methods to access itself and other methods to mangage itself.- Both
Composite
andLeaf
inherit fromComponent
. Composite
has at least one container member used to store instances ofLeaf
.- It provides methods to manage this container and implements all
virtual
methods ofComponent
by calling the correspondingvirtual
methods with the same function signature implemented byLeaf
to access allLeaf
instances stored in this container. Leaf
implements allvirtual
methods ofComponent
to access itself.- The client only needs to create an instance of
Composite
to manage and access all instances ofLeaf
.
- README.
- Code.
- Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
- Client-specified embellishment of a core object by recursively wrapping it.
- Wrapping a gift, putting it in a box, and wrapping the box.
- The three statements above imply the following:
- Replace combinational inheritance with combinational construction.
- Use multiple subclasses to decorate another subclass.
- For example:
- Create five classes:
Component
,ConcreteComponent
,Decorator
,ConcreteDecoratorA
, andConcreteDecoratorB
. - Both
ConcreteComponent
andDecorator
inherit fromComponent
. - Both
ConcreteDecoratorA
andConcreteDecoratorB
inherit fromDecorator
and are used to decorateConcreteComponent
. Component
acts as an interface.ConcreteComponent
implements allvirtual
methods ofComponent
to manage its data.Decorator
stores aComponent
pointer to an instance ofConcreteComponent
or a subclass ofDecorator
and implements allvirtual
methods ofComponent
by calling the correspondingvirtual
methods with the same function signature implemented by the instance the pointer refers to (ConcreteComponent
or subclasses ofDecorator
).ConcreteDecoratorA
andConcreteDecoratorB
override allvirtual
methods ofDecorator
by:- Calling the corresponding
virtual
methods with the same function signature implemented byDecorator
first. - Providing their own operations.
- Calling the corresponding
- The client only needs to create a
Component
pointer to a combinational-construction object like this:Compoenent* tar = new ConcreteDecoratorB( new ConcreteDecoratorA( new ConcreteComponent() ) );
. The instance ofConcreteComponent
must be created first.
- Create five classes:
- README.
- Code.
- Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
- Wrap a complicated subsystem with a simpler interface.
- The two statements above imply the following:
- Define a wrapper to encapsulate multiple classes and unify the access operations to these classes.
- For example:
- There are four classes:
SubsystemA
,SubsystemB
,SubsystemC
, andFacade
. - The three subsystem classes (
SubsystemA
,SubsystemB
, andSubsystemC
) only provide their own methods. Facade
stores three pointers to the subsystem classes and provides methods that either:- Call methods of the subsystem classes to access their functionality, or
- Manage the lifetime of the subsystem classes.
- The client only needs to create a
Facade
instance to access and manage these three subsystem classes.
- There are four classes:
- README.
- Code.
- Use sharing to support large numbers of fine-grained objects efficiently.
- The Motif GUI strategy of replacing heavy-weight widgets with light-weight gadgets.
- The two statements above imply the following:
- If the number of instances of a class is significant, the class should be separated into two parts: the shared (state-independent, intrinsic) part and the unique (state-dependent, extrinsic) part.
- The shared part is stored in the
Flyweight
. - The unique part is either stored or computed by client objects and passed
to the
Flyweight
when its operations are invoked.
- README.
- Code.
- Provide a surrogate or placeholder for another object to control access to it.
- Use an extra level of indirection to support distributed, controlled, or intelligent access.
- Add a wrapper and delegation to protect the real component from undue complexity.
- The three statements above imply the following:
- Create a
Proxy
object that holds a pointer to theRealSubject
object and provides methods to access and manage it.
- Create a
- README.
- Code.
- In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns.
- By doing so, these patterns increase flexibility in carrying out this communication.
- 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.
- Launch-and-leave requests with a single processing pipeline that contains many possible handlers.
- An object-oriented linked list with recursive traversal.
- The three statements above imply the following:
- Allow objects to handle a request, similar to the event mechanism in Qt.
- Create a
Handler
class as a base class. - The
Handler
class stores a pointer to anotherHandler
instance (usually a subclass) and provides at least two methods:- One method to set the pointer to another
Handler
instance (usually a subclass). - Another method,
handleRequest
, to call thehandleRequest
method overridden by a subclass instance.
- One method to set the pointer to another
- Subclasses of
Handler
must override thehandleRequest
method to process the request:- If the request is successfully handled, terminate the execution of the
handleRequest
method. - Otherwise, call the
handleRequest
method of the baseHandler
class. - The base
Handler
class'shandleRequest
method attempts to delegate the request to the nextHandler
instance in the chain.
- If the request is successfully handled, terminate the execution of the
- Clients only need to create multiple instances of
Handler
subclasses and organize these instances in the desired order to complete the request.
- README.
- Code.
- Encapsulate a request as an object, thereby letting you parametrize clients with different requests, queue or log requests, and support undoable operations.
- Promote "invocation of a method on an object" to full object status
- An object-oriented callback.
- The three statements above imply the following:
- Bind actions to specific objects, with or without a chain order, similar to the signal/slot mechanism in Qt.
- README.
- Code.
- Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
- Map a domain to a language, the language to a grammar, and the grammar to a hierarchical object-oriented design.
- The two statements above imply the following:
- Design an interpreter to process a language that has its own grammar for representing its words, sentences, and other constructs.
- In modern C++, this design pattern commonly works with abstract syntax trees, syntax trees, and tools like Lex (Flex) and Yacc (Bison).
- README.
- Code.
- Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
- The C++ and Java standard library abstraction that makes it possible to decouple collection classes and algorithms.
- Promote to "full object status" the traversal of a collection.
- Polymorphic traversal.
- The four statements above imply the following:
- Define a class that provides a uniform way to access elements stored in another class.
- Refer to STL containers and iterators.
- README.
- Code.
- Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
- Design an intermediary to decouple many peers.
- Promote the many-to-many relationships between interacting peers to "full object status".
- The three statements above imply the following:
- Define a class used to manage data transfer among multiple objects.
- README.
- Code.
- Without violating encapsulation, capture and externalize an object's internal state so that the object can be returned to this state later.
- A magic cookie that encapsulates a "check point" capability.
- Promote undo or rollback to full object status.
- The three statements above imply the following:
- Define two classes to manage another class:
Memento
,Originator
, andCareTaker
. Memento
is used to store a single previous state of theOriginator
.Originator
is a user-defined class that stores data and is declared as a friend class ofMemento
.CareTaker
is a class used to manage theOriginator
and utilizes a container withMemento
to store multiple previous states of theOriginator
.- It is responsible for saving the state of the
Originator
after the state has been changed and for restoring theOriginator
to a previous state if needed. - The client only needs to create an
Originator
object and pass it to aCareTaker
object. - Every time the client changes the state of the
Originator
object, they should also call thestore
method of theCareTaker
object to save the state of theOriginator
. - If the client wants to restore the
Originator
object to a previous state, they can call theundo
method of theCareTaker
object.
- Define two classes to manage another class:
- README.
- Code.
- Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
- Encapsulate the core (or common or engine) components in a Subject abstraction, and the variable (or optional or user interface) components in an Observer hierarchy.
- The "View" part of Model-View-Controller.
- The three statements above imply the following:
- There are multiple classes whose states depend on another class. Observers depend on a subject.
- When the state of the other class changes, these classes should be notified.
- When these classes are instantiated, they should be attached to an instance of the other class so that the other class can notify them that its state has changed.
- For example:
- Create four classes:
Observer
,ConcreteObserver
,Subject
, andConcreteSubject
. ConcreteObserver
andConcreteSubject
inherit fromObserver
andSubject
, respectively.Observer
provides purevirtual
methods to update its state and access its state.Subject
provides purevirtual
methods to update its state and access its state.- Additionally,
Subject
provides the following methods:- Attach
Observer
instances (usually subclasses) to it. - Detach
Observer
instances (usually subclasses) from it. - Notify all attached instances that its state has changed.
- Attach
Subject
also maintains a container to store theObserver
pointers to the attachedObserver
instances (usually subclasses).ConcreteObserver
andConcreteSubject
only need to implementvirtual
functions and manage their states.- The client only needs to use
ConcreteObserver
andConcreteSubject
to create objects and attachConcreteObserver
objects to specificConcreteSubject
objects.
- Create four classes:
- README.
- Code.
- Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
- An object-oriented state machine.
- wrapper + polymorphic wrappee + collaboration.
- The three statements above imply the following:
- Use a
State
class and its subclasses to determine how theMachine
class behaves. - For example:
- Define four classes:
State
,ConcreteStateA
,ConcreteStateB
, andMachine
. - Both
ConcreteStateA
andConcreteStateB
inherit fromState
and represent different states of the machine. State
acts as an abstract base class or interface.ConcreteStateA
andConcreteStateB
provide different implementations of theState
interface.- The
Machine
class stores a pointer to aState
object (typically one of its subclasses) and provides asetState
method to modify its state and manage the lifetime of theState
objects. - It also provides other methods to invoke actions defined by the
State
object to complete tasks. - The client only needs to create a
Machine
object, pass a specificState
object to it, and call its methods to complete tasks.
- Define four classes:
- Use a
- README.
- Code.
- Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.
- Capture the abstraction in an interface, bury implementation details in derived classes.
- The two statements above imply the following:
- Define a family of algorithms in an inheritance tree.
- A class not in this tree stores a base pointer to one of their instances and is defined for calling this family of algorithms.
- For example:
- Define five classes:
Strategy
,ConcreteStrategyA
,ConcreteStrategyB
,ConcreteStrategyC
, andContext
. ConcreteStrategyA
,ConcreteStrategyB
, andConcreteStrategyC
all inherit fromStrategy
.Strategy
provides a pure virtual method to implement a family of algorithms.ConcreteStrategyA
,ConcreteStrategyB
, andConcreteStrategyC
implement this method slightly differently according to their specific purposes, but they all aim for the same goal.Context
stores aStrategy
pointer to aStrategy
object (usually one of its subclasses) and provides a method to call the algorithm or method implemented by that object.- The client only needs to create a
Context
object, pass a specificStrategy
object (usually one of its subclasses) to it, and call the method of theContext
object.
- Define five classes:
- README.
- Code.
- Define the skeleton of an algorithm in an operation, deferring some steps to client subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
- Base class declares algorithm 'placeholders', and derived classes implement the placeholders.
- The two statements above imply the following:
- Multiple algorithms share similar steps.
- Except for some critical steps, all other steps are the same across these algorithms.
- A class inheritance hierarchy can be used to implement these algorithms.
- The base class provides:
- Implementations of the shared steps as methods.
- Pure
virtual
methods to define the critical steps. - A unique method that calls all the step methods in the appropriate order.
- A subclass representing a specific algorithm only needs to implement the
virtual
methods for the critical steps of its algorithm. - The client only needs to create a specific subclass object and call the unique method.
- README.
- Code.
- Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
- The classic technique for recovering lost type information.
- Do the right thing based on the type of two objects.
- Double dispatch.
- The four statements above imply the following:
- Utilize polymorphism to allow one class to access another class but not modify its data.
- For example:
- Define six classes:
Visitor
,ConcreteVisitor1
,ConcreteVisitor2
,Element
,ConcreteElementA
, andConcreteElementB
. Visitor
andElement
act as interfaces.Visitor
provides two purevirtual
methods that accept pointers toConcreteElementA
andConcreteElementB
as arguments, respectively.ConcreteVisitor1
andConcreteVisitor2
must provide implementations for these two methods.Element
defines a purevirtual
accept
method whose parameter is aVisitor
pointer type, allowing it to receive aVisitor
subclass object.- The client only needs to create instances of the four concrete classes
and call the
accept
methods ofElement
objects to passVisitor
objects to them.
- Define six classes:
- README.
- Code.