Are you curious to know what design patterns are? What are the GoF patterns? How are they used in software development? What are the different types of design patterns? What is the ‘design intent‘ of these patterns? If yes, you have reached the right page. In this article, I will discuss these topics and provide insight on GoF design patterns.
From Cambridge Online Dictionary:
Design(noun): “the way in which something is planned and made.”
Pattern(noun): “a particular way in which something is done, is organized, or happens.“
A Design Pattern in software engineering is:
Design patterns along with the guiding design principles play an important role in the Object-oriented analysis and design of a software system. They help to design and develop software that is robust, flexible, and maintainable.
Software patterns were first introduced in the year 1994 by the four authors, Erich Gamma et al. Their book “Design Patterns: Elements of Reusable Object-Oriented Software” contains a catalog of twenty-three patterns classified into three groups. The book provides code samples written in C++ and Smalltalk language to illustrate the use of these patterns.
The four authors also famous as the Gang of four (GoF), led to these patterns named as GoF design patterns.
These solutions or templates, use best practices in Object-oriented programming and design and have become the standard to build object-oriented software systems. They have been adopted in several Object-oriented programming (OOP) languages and find wide applications in the design and analysis of their software systems.
The 1980s saw the large-scale development of commercial applications. The failure of procedural programming (C, Fortran, Algol) to support the development of large-scale applications, led to the adoption of Object-oriented programming. This move brought in several problems in the design and development of software systems.
Many of these problems were due to the use of procedural programming practices and a lack of standards and best practices in Object-oriented software design.
Bad practices led to poorly designed systems with low cohesion and highly coupled systems. The software quality factors like correctness, reliability, integrity, usability, and maintainability suffered from poor performance.
The design patterns set up a standard by defining the construction, structure, interaction of the classes and objects; in a software system. They generally follow these three design principles:
The twenty-three design patterns are classified into three families, based on the problem they solve and are as follows:
#1. CREATIONAL DESIGN PATTERNS:
These patterns are concerned with the construction of the object.
The five Creational patterns and their design intent as stated in the GOF book, are as described below:
- Singleton: “Ensure a class has only one instance, and provide a global point of access to it.“
- Factory Method: “Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.“
- Abstract Factory: “Provide an interface for creating families of related or dependent objects without specifying their concrete classes.“
- Prototype: “Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.”
- Builder: “Separate the construction of a complex object from its representation so that the same construction process can create different representations.”
#2. BEHAVIORAL DESIGN PATTERNS:
These patterns are concerned with object interaction and delegating or handling responsibilities amongst the objects.
The eleven behavioral patterns and their design intent as stated in the GOF book are as follows :
- Chain of Responsibility: “Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.”
- Command: “Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.“
- Interpreter: “Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. “
- Iterator: “Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.“
- Mediator: “Define 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 you vary their interaction independently.“
- Memento: “Without violating encapsulation, capture and externalize an object’s internal state so that the object can be returned to this state later.“
- Observer: “Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.“
- State: “Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.“
- Strategy: “Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.”
- Template Method: “Define the skeleton of an algorithm in an operation, deferring some steps to client subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.“
- Visitor: “Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.“
#3. STRUCTURAL DESIGN PATTERNS:
These patterns are concerned with composing and structuring class hierarchies for the development of a robust system.
The seven structural patterns and their design intent as stated in the GOF book are as follows :
- Adapter: “Convert the interface of a class into another interface clients expect. The adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.“
- Bridge: “Decouple an abstraction from its implementation so that the two can vary independently. “
- Composite: “Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. “
- Decorator: “Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. “
- Facade: “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: “Use sharing to support large numbers of fine-grained objects efficiently“
- Proxy: “Provide a surrogate or placeholder for another object to control access to it. “
The design patterns are also classified as Class or Object design patterns based on the Scope and as quoted from GoF are:
- Class Design patterns: “Class patterns deal with relationships between classes and their subclasses. These relationships are established through inheritance, so they are static-fixed at compile-time.“
- Object Design patterns: “Object patterns deal with object relationships, which can be changed at run-time and are more dynamic.” Most patterns belong to this category. The object references change or are dynamically assigned in these types of patterns.
The software development of a product requires proper analysis and design of the proposed system. The system needs to reflect the characteristics of good software design including simplicity, coupling, cohesion, information hiding, performance, and security. The patterns used together help architect and build such software systems.
The patterns are not disjoint pieces of entities that work individually, they relate to each other and collaborate to form a larger system. They can be customized to best fit and collaborate with the design.
Use of design patterns, design principles, and best practices have known to develop systems that are robust, maintainable, and flexible.
Many software libraries and frameworks in several OOP languages have used these patterns to architect, design, and develop their systems. The C# .net framework, Java framework are examples of such a system.
As software systems evolved and grew in complexity, many design patterns have been introduced and documented in the Industry. These patterns can be sourced from pattern conferences.
Design patterns help to design and develop robust software systems that have low coupling and strong cohesion. Patterns incorporate best practices in OOP and offer solutions to software design problems. They are used to solve a design problem in a given context.
The GoF were the first to catalog twenty-three patterns, classified into structural, behavioral, and creational patterns. Many popular frameworks and libraries use these patterns.
The patterns are not disjoint pieces of software solutions. They relate to each other and combine to form larger systems. Collaborating patterns help build better software systems. Some patterns better relate to other patterns and fit well the solution design.
Proper use of design patterns leads to good system design and their abuse leads to disadvantages that far outweigh the benefits. A good analysis of the problem in context leads to the right or no usage of the pattern.
With time, complex and evolving software systems have led to the discovery of new design patterns. Experts in the industry introduce and catalog them in several pattern conferences.
Please do let me know your views and comments about this article. If you like this article, please do share it on social.