Design patterns are recurring solutions to common design problems in software development. They provide a template for solving specific issues in a flexible and reusable way. By encapsulating best practices, design patterns promote maintainability, scalability, and clarity in software design.
- SOLID
- Gamma Categorization (Erich Gamma)
- Categorizes design patterns based on their real-world applications i.e which part of the code they usually appear in.
- Divides design patterns into following three categories
- Creational Patterns
- Used when the object is being created or constructed.
- Implicit Creational Patterns - where the contructor call is not needed to create the object.
- Explicit Creational Patterns - where constructor is explicitly called to create the object.
- Wholesale Object Createion - where object is created with a single statement
- Piecewise Object Creation - where multiple steps have to followed for object creation.
- Singleton, Factory, Abstract, Builder and Prototype are examples of Creational Patterns.
- Structural Patterns
- Used to define the structure of class e.g. how an interface is implemented or how the class member are defined.
- Focuses on good API design and relationship between objects.
- Adapter, Bridge, Composite, Decorator, Facade, Flyweight and Proxy are examples of Structural Patterns.
- Behavioral Patterns
- Have on general theme to them.
- Ususally focuses on creating algorithms and establishing communication mechanism between different objects.
- Command, Iterator, Mediator, Observer, Visitor, etc are examples of Behavioral Patterns.
- Creational Patterns
- Builder Pattern
- Builder Pattern is a type of Piecewise Creational Patterns.
- Fluent Builders allow users to chain the build commands together like
builder.do_this().do_that()
. - Groovy-Style Builders allow users to create Domain-Specific Languages that makes use of uniform initialization e.g. The nested groovy-style initialization looks
A{ B{ }, C{ D{ } } }
. - Builder-Facets is a combination of Builder and Facade Pattern and is used when the object being built is highly complex and requires the use of multiple builders.
- Factory Pattern
- Factory Pattern is a type of Wholesale Creational Pattern where the entire building process is handed over to a factory method or a factory class to avoid any convoluted API for object creation.
- Factory Method, Factory Class and Abstract Factory Class are all type of Factory Pattern.
- Abstract Factory Classes are used to create heirarchy of factories that create different object in the heirarchy.
- Prototype Pattern
- Prototype Pattern is a type of Creational Pattern where the new object is built by making modifications on an already existing complex object, or a prototype, by creating its deep copy, or cloning it.
- Prototyping can also be done via serialization as serialization traverses the entire object graph and needs serlialization implementation for each of the object present in it and the object that was serialized when deserialized creates a deep copy of the same.
- Singleton Pattern
- Singleton Pattern is a form of Creational Pattern where an object is or should be instatntiated only once.
- Singleton pattern e.g. is used when the constructor call is expensive and we need to provide the same instance to everyone.
- It also allows lazy instantiation and thread safety.
- Monostate Pattern is a variation of Singleton Pattern where all the data members of the class are static and getters and setter are called for them. This pattern is highly prone to bugs and not very inheritance-friendly due to the static members.
- Multiton Pattern is also a variation of Singleton Pattern where multiple singleton objects are created based on a given range or keys.
- Adapter Pattern
- Adapter Pattern is a form of Structural Pattern where a given interface is 'adapted' or transformed to conform to the required interface.
- Used when the given interface doesn't have the required functionality out of the box or if it doesn't conform to the required structural specs e.g. exposes some internal data that should be private in your program's context or if the given interface might change in the future.
- Bridge Pattern
- Bridge Pattern is a type of Structural Pattern where an interface(heirarchy) is decoupled from its implementation(heirarchy) so that the two can vay independently.
- It is useful when there are two orthogonal dependencies that need to evolve independently, allowing changes in one heirarchy to not affect the other and to also avoid 'Cartesian Entity Explosion'.
- Pimpl Idiom Pattern is also a variation of Bridge Pattern.
- Composite Pattern*
- Composite Pattern is a variation of Structural Pattern that allows user to interact with both scalar or composite objects uniformly i.e. through the same API.
- Decorator Pattern*
- Decorator Pattern is another variation of Structural Pattern which facilitates the addition of behaviours to individual objects.
- Decorator Pattern can be implemented in C++ by Aggregating the existing object or by inherting from the decorated object.
- Facade Pattern
- Facade Pattern is a type of Strucutural Pattern where an easy-to-use or a simpler API is build on top of a rather complex collection of sub-sytems, trying to provide a unified interface over the interfaces of the multiple sub-sytems.
- Facade Pattern can be seen in the BuilderFacets example where the a simpler API of
PersonBuilder
is provide to initialize the collection of multiple complex attributes.
- Flyweight Pattern
- Flyweight Pattern is a form of Structural Pattern which helps in reducing memory usage by sharing the objects with similar states across multiple contexts.
- It is useful when a large number of objects with same states have to be created and each object is either very large or creating the object adds significant overhead.
- Proxy Pattern
- Proxy Pattern is another type of Structural Pattern which is used to create an interface for a resource in order to control access to it as the resource might be expensive, difiicult to construct or requires added functionality.
- Key difference between Proxy and Decorator Pattern is that a Proxy provides an identical interface by replicating the members, adds the required functionalities to the redefined members, whereas a Decorator provides an enhanced interface to the underlying resource by aggregating the resource.
- Simplest Examples of Proxy Pattern are the smart_pointers of STL library.
- Chain Of Responsibility
- Chain of Responsibility is a Behavioral Pattern which allows a object to pass the request along a chain of potential handlers until one of them handles the request.
- It decouples the sender of an object fromm its reciever by giving more than one object the chance to handle the request.
- Command Pattern
- Command Pattern is a Behavioral Pattern in which each operation/command performed is stored as an object that contains all the information required to perform the operation/command.
- It provides useful functionality like undoable commands, command queues, macro commands etc.
- Commad Query Separation is variation of Command Pattern.
- Interpreter Pattern
- Interpreter Pattern is a type of Behavioral Pattern that is used to process structured textual data by the process of lexing and and parsing.
- Lexing is the process of separating the text into lexical tokens (tokens that have some meaning like 'class' keyword in C++).
- Parsing is the process of turning the tokens into machine understandable statements.
- Modern Language compiler use the interpreter to parse the code.
- Interator Pattern
- Iterator Pattern is a variation of Behavioral Pattern that provides an API to traverse a data structure.
- An iterator object keeps a reference to the current element and knows how to move to the next element.
- All the data structures in C++ STL have iterators that allows their traversal.
- Mediator Pattern
- Mediator Pattern is type of Behavioral Pattern that facilitates communication between components through a central component (mediator), rather than all components directly communicating with each other.
- Mediator keeps track of all the components whenever they come in and out of the system, which is much safer than individual components accessing a direct reference of some other component that may have gone out of the system.
- Main server of a chat Application is an example of mediator pattern.
- Memento Pattern
- Memento Pattern is a Behavioral Pattern that provides the capture and restore functionality to a system by storing the state of system in an immutable format.
- Memento Pattern is different from Command Pattern in the sense that Command Pattern stores the commands as objects in the system and inorder to restore the system the commands have to be provided with undo functionality, whereas in Memento Pattern the state of the system is stored as an object which can be restored by just replacing the current state with the required state object.
- Observer Patter
- Observer Pattern is a another variation of Behavioral Pattern which facilitates the communication between different components by notifying the components about any state changes, without needing any implementation details of the notified componenet.
- Observer is the components that needs to be notified and the Observable is the componenet that notifies the observers.
- State Pattern
- State Pattern is a type of Behavioral Pattern that facillitates the transitioning of an object from one state to another based on either changes in internal state or triggered by an external event (Observer Pattern).
- State Machine is a system that defines the transitions that an object goes through during its lifetime.
- Strategy Pattern
- Strategy Pattern is a variation of Behavioral Pattern where the behavior of a system is determined partially at either runtime or compile-time.
- Strategy Pattern is also known as Policy Pattern.
- Strategy Pattern is similar to Abstract Factory Pattern in the sense that both decouples client code from implementation details, however Abstract Factory Pattern is used to instantiate family of related objects whereas Strategy Pattern is used to alternate between different strategies dynamically.
- Template Pattern
- Template Pattern is type of Behavioral Pattern that defines the skeleton for an algorithm through an interface, details of which are then determined by the inheritors.
- Visitor Pattern
- Visitor Pattern is a form of Behavioral Pattern that allows the addition of new operations or functionalities to existing heirarchy of components without breaking either the Open Closed Principle or the Single Responsibility Principle.