Ever since software engineering has come to life, software engineers have repeatedly faced situations wherein they have to solve similar problems over and over again. And being a software engineer I can tell you that it is very annoying. So, what can we do about it? How do we solve our similar software problems? Well, the answer to these questions is, by using Software Design Patterns. Let’s talk about it in more detail.
What are Design Patterns?
Design patterns provide solutions to common software design problems. Design patterns are not about designs as linked lists that can be encoded in classes and reused as is. In a particular context, design patterns aim to solve the problem of object communication and customization of classes to solve a general design problem, rather than solving large scale problems of software architecture. A design pattern identifies relevant objects, factors them into participating classes and establishes a relationship among them.
Design pattern is like a template that can be applied in different situations. While using a design pattern, it is also important to keep in mind that it is the correct pattern to be used in that particular context, else you may end up over-complicating your code. Design patterns help choosing a design that makes the system reusable.
In general, a pattern has four essential elements.
- The Pattern name describes the problem, its solution and its consequences. It helps design at a higher level of abstraction and easily talk about it with our colleagues.
- The Problem describes when to apply a pattern. It sometimes includes a list of conditions that must be met before a pattern can be applied to solve it.
- The Solution does not describe any concrete implementation. It rather describes the components of design pattern, their relationships, responsibilities and collaborations.
- The Consequences are the results and trade-offs of applying a pattern. They are critical for evaluating the software cost and benefits of applying a particular design pattern.
The Gang of Four (GoF)
Four authors, namely Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, together are known as the Gang of Four (GOF). The GoF is the author of a 395 pages book Design Patterns: Elements of Reusable Object-Oriented Software, published in 1994. The book describes recurring solutions to common problems in software design.
Design Pattern Categories
There are twenty-three design patterns defined by the GoF. At a higher level, these patterns are grouped into three categories depending on the nature of the design problem they intend to solve. Next is a small description of the three categories and list of their respective patterns.
1. Creational Design Patterns
These patterns deal with the process of object creation in such a way that they can be decoupled from their implementing system. This provides more flexibility in deciding which objects need to be created for a given use case/ scenario.
- Factory Method : Creates instances of derived classes
- Abstract Factory : Creates instances of several classes belonging to different families
- Builder : Separates an object construction from its representation
- Prototype : Creates a duplicate object or clone of the object
- Singleton : Ensures that a class has only one instance
2. Structural Design Patterns
These patterns deal with the composition of object structures. The concept of inheritance is used to compose interfaces and define various ways to compose objects for obtaining new functionalities.
- Adapter : Matches interfaces of different classes
- Bridge : Separates an object’s abstraction from its implementation
- Composite : A tree structure of simple and composite objects
- Decorator : Adds responsibilities to objects dynamically
- Façade : A single class that represents an entire complex system
- Flyweight : Minimizes memory usage by sharing as much data as possible with similar objects
- Proxy : Provides a surrogate object, which references to other object
3. Behavioral Design Patterns
These patterns deal with the process of communication, managing relationships, and responsibilities between objects.
- Null Object : Designed to act as a default value of an object
- Chain of Responsibility : Passes a request among a list or chain of objects
- Command : Wraps a request under an object as a command and passes to invoking object
- Interpreter : Defines the grammar for instructions that form part of a language or notation
- Iterator : Provides a standard interface for traversing a collection of items in an aggregate object
- Mediator : Reduces coupling between classes that communicate with each other
- Memento : Captures the current state of an object and store it in a way that it can be restored
- Observer : Allows an object to publish changes to its state, to which other objects may subscribe
- State : Alters the behaviour of an object as its internal state changes
- Strategy : Creates a family of interchangeable algorithms from which required process is chosen at run-time
- Visitor : Separates a relatively complex set of structured data classes from the functionality, that may be performed upon the data that they hold
- Template Method : Defines the basic steps of an algorithm and allows the implementation of the individual steps to be changed
I hope this helps you get an overview of GoF design patterns and apply them while designing your software.