Design patterns are typical solutions to commonly occurring problems in software design. They are like pre-made blueprints that you can customise to solve a recurring design problem in your code.
You can’t just find a pattern and copy it into your program, the way you can with off-the-shelf functions or libraries. The pattern is not a specific piece of code, but a general concept for solving a particular problem. You can follow the pattern details and implement a solution that suits the realities of your own program.
Patterns are often confused with algorithms, because both concepts describe typical solutions to some known problems. While an algorithm always defines a clear set of actions that can achieve some goal, a pattern is a more high-level description of a solution. The code of the same pattern applied to two different programs may be different.
An analogy to an algorithm is a cooking recipe: both have clear steps to achieve a goal. On the other hand, a pattern is more like a blueprint: you can see what the result and its features are, but the exact order of implementation is up to you.
Types of Design Patterns
1. Creational Design Patterns
Creational patterns often used in place of direct instantiation with constructors. They make the creation process more adaptable and dynamic. In particular, they can provide a great deal of flexibility about which objects are created, how those objects are created, and how they are initialized.
|DESIGN PATTERN NAME||PURPOSE|
|Builder||Builder design pattern is an alternative way to construct complex objects and should be used only when we want to build different types of immutable objects using same object building process.|
|Prototype||Prototype design pattern is used in scenarios where application needs to create a large number of instances of a class, which have almost same state or differ very little.|
|Factory||Factory design pattern is most suitable when complex object creation steps are involved. To ensure that these steps are centralized and not exposed to composing classes.|
|Abstract factory||Abstract factory pattern is used whenever we need another level of abstraction over a group of factories created using factory pattern.|
|Singleton||Singleton enables an application to have one and only one instance of a class per JVM.|
2. Structural Design Patterns
Structural design patterns show us how to glue different pieces of a system together in a flexible and extensible fashion. These patterns help us guarantee that when one of the parts changes, the entire application structure does not need to change.
|DESIGN PATTERN NAME||PURPOSE|
|Adapter||An adapter convert the interface of a class into another interface clients expect. It lets classes work together that couldn’t otherwise because of incompatible interfaces.|
|Bridge||Bridge design pattern is used to decouple a class into two parts – abstraction and it’s implementation – so that both can evolve in future without affecting each other. It increases the loose coupling between class abstraction and it’s implementation.|
|Composite||Composite design pattern helps to compose the objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.|
|Decorator||Decorator design pattern is used to add additional features or behaviors to a particular instance of a class, while not modifying the other instances of same class.|
|Facade||Facade design pattern 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.|
|Flyweight||Flyweight design pattern enables use sharing of objects to support large numbers of fine-grained objects efficiently. A flyweight is a shared object that can be used in multiple contexts simultaneously. The flyweight acts as an independent object in each context.|
|Proxy||In proxy design pattern, a proxy object provide a surrogate or placeholder for another object to control access to it. Proxy is heavily used to implement lazy loading related usecases where we do not want to create full object until it is actually needed.|
3. Behavioral Design Patterns
Behavioral patterns abstract an action we want to take on the object or class that takes the action. By changing the object or class, we can change the algorithm used, the objects affected, or the behavior, while still retaining the same basic interface for client classes.
|DESIGN PATTERN NAME||PURPOSE|
|Chain of responsibility||Chain of responsibility design pattern gives more than one object an opportunity to handle a request by linking receiving objects together in form of a chain.|
|Command||Command design pattern is useful to abstract the business logic into discrete actions which we call commands. These command objects help in loose coupling between two classes where one class (invoker) shall call a method on other class (receiver) to perform a business operation.|
|Interpreter||Interpreter pattern specifies how to evaluate sentences in a language, programatically. It helps in building a grammar for a simple language, so that sentences in the language can be interpreted.|
|Iterator||Iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.|
|Mediator||Mediator pattern defines 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 us vary their interaction independently.|
|Memento||Memento pattern is used to restore state of an object to a previous state. It is also known as snapshot pattern.|
|Observer||Observer pattern defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. It is also referred to as the publish-subscribe pattern.|
|State||In state pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class. There shall be a separate concrete class per possible state of an object.|
|Strategy||Strategy pattern is used where we choose a specific implementation of algorithm or task in run time – out of multiple other implementations for same task.|
|Template method||Template method pattern defines the sequential steps to execute a multi-step algorithm and optionally can provide a default implementation as well (based on requirements).|
|Visitor||Visitor pattern is used when we want a hierarchy of objects to modify their behavior but without modifying their source code.|
Benefits of Design Pattern
|Saves time||Design Patterns are already defined and provides industry standard approach to solve a recurring problem, so it saves time if we sensibly use the design pattern.|
|Reusability and Robustness||Using design patterns promotes reusability that leads to more robust and highly maintainable code. It helps in reducing total cost of ownership (TCO) of the software product.|
|Easy to understand and easy to debug||Since design patterns are already defined, it makes our code easy to understand and debug. It leads to faster development and new members of team understand it easily.|
|Abstraction is maintained||Since code will be maintained and organised well so abstraction is expected to be at great extent.|
|Extensible||Huge code will be modularised and easy to extend the code. Elasticity could be realised well. Writing and adding new code is easy with proper design patterns.|