Gearing up for your next interview and still confused about where to start in design patterns? This article lays the groundwork for understanding design patterns.
Problems that occur very often in industrial tech life usually have well-defined solutions, which are flexible, modular and more understandable. These solutions when abstracted become design patterns.
What is Gang Of Four?
The four authors Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides published a book over 20 years ago. The name of the book was “Design patterns: Elements of reusable object-oriented software”. The book became so famous that it still continues to be the best seller in system design. Hence, all of them became popular as GOF (Gang of Four). The GOF wrote the book in C++. It can be also applied for Java as both are object-oriented languages.
The design patterns of GOF are famous and according to them, these are categorised as:
Let us discuss each pattern in details:
Creational design patterns are related to how objects are created from classes. Adding new objects to your code may sound trivial but unthoughtful littering code with instance creations can lead to headaches down the road. The creational design pattern gives suggestions on how to encapsulate object creations.
Its types are:
- Builder Pattern: As the name implies, the builder pattern is used to build objects. Sometimes objects created can be complex or require unique elaboration for the construction process. This complex type can be simplified by builder patterns. The builder generally builds composite or aggregate objects. The builder pattern encapsulates the process of building a complex object. It separates the representation of the object and its construction and this separation allows us to construct different representations using the same construction process.
- Prototype Pattern: In this pattern we create objects by copying the existing objects. The objects whose copies are made is called a prototype. In this pattern, a prototype interface is implemented which helps to create a clone of the current object. This pattern is used when the creation of the object directly is costly. Let us consider a case in which an object is to be created after a costly database operation. The ideal way will be to cache the object, return its clone on next request and update the database as and when needed thus reducing database calls.
- Singleton Pattern: In this pattern, we are allowed to create one and only one instance of a class. Cache, thread pools, registries are examples of having a single instance. Since this pattern has only one instance of the class it assures that the instance has a global point of access.
- Factory Method Pattern: As a factory produces goods, a software factory produces objects. Usually, an object is created by ClassXYZ objXYZ = new ClassXYZ(). The problem with the above approach is that the code using the ClassXYZ‘s object, suddenly now becomes dependent on the concrete implementation of ClassXYZ. There is nothing wrong with creating objects with the new keyword but sometimes it tightly couples our code to the concrete implementation class which is a violation of code to interface and not to an implementation. The factory method provides an interface for object creation but delegating the actual instantiation of objects to subclasses.
This type of pattern is concerned with the composition of classes i.e, how classes are constructed or made. These are of following types:
- Adapter Pattern: When people of two different states sit together for communication a language interpreter sits between them translates the conversation, thus enabling communication. The adapter pattern works in a similar way it sits between two incompatible classes and helps them work together. Hence, this allows incompatible classes to work together by converting the interface of one class as expected by the client.
- Bridge Pattern: The work of a bridge is to connect two endpoints. The bridge pattern works similarly, it describes how to pull apart two software layers fused in a single class hierarchy and put together into a parallel class using a bridge. The bridge pattern varies the abstraction independently of implementation and thus decoupling the two in the process.
- Composite Pattern: Composite means made up of one. This pattern treats the whole and individual part as one. Example a tree is made up of several leaf and branches where each part is a subtree. The root is top-level composite and its children are composites of themselves or root nodes Thus, it is defined as the composition of objects into tree structures to represent part-whole hierarchies.
- Decorator Pattern: Generally decorations are done to make the things more attractive. Similarly, the decorator pattern adds new functionality to objects without modifying classes. The strategy is to wrap the existing object with the decorator object that usually implements the same interface as a wrapped object.
- Facade Pattern: Facade means to hide a less pleasant reality. In similarity to the definition of the facade, this pattern hides the complexity of an interface or a subsystem. Formally, it is defined as the single uber interface to one or more subsystems or interfaces intending to make use of the subsystem easier.
- Flyweight: It is a special category in boxing for lightweight boxers. In a similar pattern, the intent is to reduce the bloated code to more compact and lean representation which uses less memory. It is defined as a sharing state among a large number of fire grained objects for efficiency.
- Proxy Pattern: As proxy attendance is a very famous technique in colleges, the proxy pattern is responsible for representing another object called subobject in front of clients. The benefit is the real subject is shielded from clients. The pattern is defined as a mechanism to provide a surrogate or placeholder for another object to control access to it.
This pattern dictates the interaction of classes and objects amongst each other and delegation of responsibilities. These are categorised as follows:
- Chain of Responsibility Pattern: The pattern is defined as decoupling the sender of a request from its receiver by chaining the receiving objects together and passing the request along the chain until the object handles it.
- Observer Pattern: This pattern can be well understood by the example of social media. If you follow someone on Twitter you get their updates i.e., you are asking Twitter to receive the tweets. A subject(twitter) can have many observers(followers). The pattern is described as a one to many dependencies between objects so that when one object changes state all the dependents are notified.
- Interpreter Pattern: The pattern uses a class to represent each grammar rule(automata theory). It is described as the way to represent the grammar of a language along with an interpreter that uses the representation to interpret the sentences in the language.
- Command Pattern: The pattern is defined as representing an action or a request as an object that can be passed to other objects as parameters, allowing a parameterization of clients with requests or actions. The request can be later queued or logged.
- Iterator Pattern: Iterate means to do something repeatedly. This pattern allows traversing the elements of an aggregate or a collection of sequentially without exposing the underlying implementation.
- Mediator pattern: Mediator is defined as the person who sits between two conflicting clients to agree. In the same manner, this pattern is defined as encouraging loose coupling among objects by encapsulating their interactions in a mediator object, thus avoiding the need of individual objects to refer to each other directly and allow to vary object interactions completely.
- Memento Pattern: The literal meaning of memento is an object kept as a reminder for a person or an event. In this pattern, we capture the internal state of an object without exposing the internal structures so that the object can be restored to its state in future.
- State Pattern: This pattern allows an object to change behaviour when its internal state changes so that it appears to change its class.
- Template Pattern: A template can be thought of as an abstract structure that can be customised in specific situations. In this context the pattern allows subclasses to define parts of an algorithm without modifying the overall structure of the algorithm.
- Strategy Pattern: This pattern is one of the simplest patterns to comprehend. It allows grouping related algorithms under an abstraction, which the client code against. The abstraction allows switching out one algorithm for another without modifying the client.
- Visitor Pattern: The pattern allows us to define an operation for a class or a class hierarchy without changing the classes of elements on which the operation is performed.
In detail to every pattern there exist the class diagrams when we study in brief. Every pattern is used differently in various scenarios. In real-world, system design plays an important role as it closes the gap between the designers and UI engineers who work on multiple products and often re-create duplicate work done by other teams.