Design Patterns
Creational design patterns
Factory pattern
The Factory pattern is a creational pattern that provides a template that can be used to create objects. It is used in complex situations where the type of the object required varies and needs to be specified in each case.
It does not use the new
keyword directly to instantiate objects. This means that it does not explicitly require the use of a constructor to create objects. Instead, it provides a generic interface that delegates the object creation responsibility to the corresponding subclass.
Constructor pattern
The Constructor pattern, as the name defines, is a class-based pattern that uses the constructors present in the class to create specific types of objects.
Singleton pattern
The Singleton pattern is a type of design pattern that restricts the instantiation of a class to a single object. This allows the class to create its instance the first time it is instantiated. However, on the next try, the existing instance of the class is returned. No new instance is created.
Builder pattern
The Builder pattern is a type of a creational design pattern that helps in building complex objects using simpler objects. It provides a flexible and step-by-step approach towards making these objects. It also shields the representation and process of creation.
Prototype pattern
The Prototype pattern is used to instantiate objects with some default values using an existing object. It clones the object and provides the existing properties to the cloned object using prototypal inheritance.
In prototypal inheritance, a prototype object acts as a blueprint from which other objects inherit when the constructor instantiates them. Hence, any properties defined on the prototype of a constructor function will also be present in the cloned object it creates.
Abstract pattern
We use the Factory pattern to create multiple objects from the same family without having to deal with the creation process. The Abstract pattern is similar. The difference is that it provides a constructor to create families of related objects. It is abstract, which means that it does not specify concrete classes or constructors.
Structural design patterns
Decorator pattern
The Decorator pattern focuses on adding properties, functionalities, and behavior to existing classes dynamically. The additional decoration functionalities aren’t considered essential enough to be a part of the original class definition since they can cause clutter. Hence, the Decorator pattern lets us modify the code without changing the original class.
Unlike creational patterns, the Decorator pattern is a structural pattern that does not focus on object creation but rather on decoration. Hence, it doesn’t rely on prototypal inheritance alone. It takes the object and keeps adding decoration to it. This makes the process more streamlined. Let’s look at an example to understand this concept better.
The illustration below shows that ice-cream toppings can be a part of the Decorator pattern for a plain vanilla cone.
WaferSprinklesBrownie
Ice-cream toppings can be implemented using the Decorator pattern
Facade pattern
The word “facade” means a deceptive front or appearance. Following this definition, a Facade pattern provides a simpler interface that hides the complex functionalities of a system. The Facade pattern allows us to hide all the messy logic from the client and only display the clear and easy-to-use interface to them. This allows the client to interact with an API easily in a less error-prone way and without accessing the inner workings directly.
Adapter pattern
The Adapter pattern allows classes that have different interfaces (properties/methods of an object) to work together. It translates the interface for a class to make it compatible with another class.
This pattern is useful if an API is modified or new implementations are added to it. In this case, if the other parts of a system are still using the old API, the Adapter pattern will translate the interface so that the two can work together. The illustration below demonstrates the use of the Adapter pattern.
Concept for the Adapter pattern
Bridge pattern
The Bridge pattern allows separate components with separate interfaces to work together. It keeps an object’s interface separate from its implementation, allowing the two to vary independently.
An example is controlling an air conditioner with a remote. The air conditioners can be of different types and each of them is controlled by a different remote. The remotes can vary, that is, a new one with better features can be introduced, but that won’t make any changes to the air conditioner classes. The same goes the other way round. The Bridge pattern allows input and output devices to work together but vary independently.
Composite pattern
The Composite pattern is used to structure objects in a tree-like hierarchy. Here, each node of the tree can be composed of either child node(s) or be a leaf (no children objects). This pattern allows the client to work with these components uniformly, that is, a single object can be treated exactly how a group of objects is treated.
This pattern allows the formation of a deeply-nested structure. If a leaf object receives the request sent by the client, it will handle it. However, if the recipient is composed of children, the request is forwarded to the child components.
A Composite pattern consists of the following:
-
Component: An abstract class that contains methods such as
add
,remove
, andget
that are used in managing the children. The component can be a leaf object or composite. -
Composite: This is the subclass that implements a component. It is composed of other components (children).
-
Leaf: This is the subclass that implements a component. It does not have children.