Design Patterns: How many are there, benefits, and which ones are the best?

13/06/2023 Author: Rafael Gallegos 12 min de lectura
¡Comparte!

Design Patterns are general-purpose solutions for problems that arise repeatedly throughout software development. In other words, they are ready-made, well-thought-out, tested, and approved solutions for common situations that arise in day-to-day development.

Think back to when you were a child and played a video game for the first time. Like with any new challenge, it took you a long time to progress through each stage and move on to the next one. The second or third time was a bit faster because you were already familiar with the game's interface and language. You even had friends who also played it and exchanged tips to achieve better results. Definitely, the more you played, the more skilled you became, and you reached the point of discovering shortcuts to reach the goal much faster with a higher score.

It's highly likely that after becoming a fan of a video game, you looked for others in the same category to continue testing the skills you gained. You found certain relationships or similarities with the previous video game that allowed you to master the new one more quickly and with better results.

Design Patterns work in a similar way to the examples above. In simple terms, they are pre-established solutions for common problems that software developers reuse to create better products following best practices, without having to start from scratch or invent something entirely new.

In this guide, we will explain what a design pattern is and help you differentiate between its 23 types, in addition to understanding their benefits.

What is a Design Pattern in Software Engineering?

In simple terms, Design Patterns are general-purpose solutions for problems that arise repeatedly throughout software development. In other words, they are ready-made, well-thought-out, tested, and approved solutions for common situations that arise in day-to-day development.

The term Design Patterns is closely related to Software Architecture and Engineering, specifically connected to the object-oriented paradigm.

These solutions are highly important in a programmer's education as they eliminate the need to reinvent solutions constantly. Knowing how to apply a Design Pattern in your code architecture ensures that any problem will be resolved.

When did Design Patterns emerge?

Design Patterns emerged through experiences in software projects, primarily after the widespread adoption of object-oriented programming. In fact, almost everything in software engineering originated from experiments and continues to evolve.

Design Patterns became known when software engineers Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides decided to establish and catalog common problems and ways to solve them.

In 1994, they released the book "Design Patterns: Elements of Reusable Object-Oriented Software," which became a kind of bible on this subject.

The quartet became known as the "Gang of Four" or simply GoF.

What are the 3 Types of Design Patterns?

There are 23 classic Design Patterns, although at least 26 Design Patterns have been discovered to date.

Design Patterns can be divided into three types, organized by their intent: Creational Design Patterns, Structural Design Patterns, and Behavioral Design Patterns.

Tipos-de-Design-Patterns

1. Creative Design Patterns

A creative design pattern deals with the creation and initialization of objects, providing guidance on which objects to create for a given situation. These design patterns are used to increase flexibility and reuse existing code.

  • Factory Method: Creates objects with a common interface and allows a class to defer the instantiation to its subclasses.

  • Abstract Factory: Creates a family of related objects.

  • Builder: Provides a step-by-step approach to creating complex objects, separating construction from representation.

  • Prototype: Supports copying existing objects without making the code dependent on classes.

  • Singleton: Restricts the instantiation of a class to a single instance.

2. Structural Design Patterns

A structural design pattern deals with the composition of classes and objects or how to assemble objects and classes into larger structures.

  • Adapter: How to change or adapt an interface to that of another existing class to enable incompatible interfaces to work together.

  • Bridge: A method to decouple an interface from its implementation.

  • Composite: Leverages a tree structure to treat individual objects and compositions of objects uniformly.

  • Facade: Defines a high-level interface to simplify the usage of a large amount of code.

  • Flyweight: Minimizes memory usage by sharing data with similar objects.

  • Proxy: How to represent an object with another object to enable access control, reduce costs, and reduce complexity.

3. Behavioral Design Patterns:

A behavioral design pattern deals with communication between objects and how responsibilities are assigned among objects.

  • Chain of Responsability: A method for delegating commands to a chain of processing objects.

  • Command: Encapsulates a command request as an object.

  • Interpreter: Supports the use of language elements within an application.

  • Iterator: Supports sequential access to the elements of a collection.

  • Mediator: Facilitates simple communication between classes.

  • Memento: A process for saving and restoring the original internal state of an object.

  • Observer: Defines how objects are notified of changes in other objects.

  • State: How to alter the behavior of an object when its internal state changes.

  • Strategy: Encapsulates an algorithm within a class.

  • Visitor: Defines a new operation in a class without modifying the class.

  • Template Method: Defines the skeleton of an operation while allowing subclasses to refine certain steps.

What is the importance of Design Patterns?

Design Patterns focus on the reuse of solutions. While not all problems are the same, by dividing them and finding similarities with previously solved problems, it is possible to apply Design Patterns and obtain solutions.

But why should programmers care about using Design Patterns?

Because software evolves and requires constant maintenance. Designing software that is of high quality and, more importantly, reusable, is not an easy task. However, Design Patterns are there to facilitate this activity.

Moreover, with Design Patterns, it is easier to read someone else's code. During the development stage, specific solutions are often created. However, creating generalizations can support the work of everyone, and that's why understanding code written by other developers becomes much easier.

Once you gain experience in applying Design Patterns, the solutions become patterns that have been tested and approved by the market, and they are used by the best professionals in the world.

What are the Benefits of Using these Patterns?

As the patterns have already been used and tested, they represent a productivity gain for developers. This is because they prevent wasting time and energy on solving common problems

  • Proven Solutions

Design Patterns provide a proven and reliable solution for a common problem, which means that software developers don't have to 'reinvent the wheel' when that problem occurs.

  • Reusability

Design Patterns can be modified to solve many types of problems and are not tied to a single problem.

  • Avoidance of Code Refactoring

Since the design pattern is already the optimal solution for the problem, it can help avoid code refactoring.

  • Reduced Codebase Size

Each pattern helps software developers change how the system works without a complete redesign. Additionally, as an 'optimal' solution, the design pattern often requires less code.

The Top 7 Design Patterns

Although there are 23 listed Design Patterns, there are 7 considered to be the most influential. Here, we will describe the top 7 software Design Patterns, why they are important, and when to use them.

1. Singleton 

The Singleton design pattern falls under the 'Creational Design Patterns' type, restricting the creation of objects for a class to a single instance and providing global access to a global variable.

For example, many web developers lock the 'Site Map' into a single version that has global scope. Additionally, other patterns like Factory Method, Builder, and Prototype can make use of Singletons. Facade and State objects are also often Singletons.

While you may only have or need one instance of a class, it does not necessarily mean that it is the right time to use a Singleton pattern to lock that object or force it into a global state. Singletons are a controversial design pattern, and some even argue that Singletons are an anti-pattern that should be avoided because encapsulating an object restricts future flexibility.

Design Pattern- Singleton

2. Factory Method 

In the Factory Method, a "creation" design pattern, developers create objects with a common interface but allow a class to defer the instantiation to its subclasses. The factory method promotes loose coupling and code reuse, acting as a "virtual builder" that works with any class implementing the interface and allowing subclasses the freedom to choose the objects being created. When new classes are needed, they can be added to the factory.

This pattern is not suitable for simple scenarios where developers risk overcomplicating processes to use a design pattern.

Design Pattern- Factory Method

3. Facade 

The Facade design pattern belongs to the "Structural Design Patterns" type, which helps provide an interface (class) to access a large amount of code/multiple objects.

It encapsulates complexities of various subsystems (often organized into a class) behind a simple interface. For example, an e-commerce client only wants one point of interaction with a brand, rather than individually communicating (interconnecting) with each system supporting the sale, such as product inventory, authentication, security, payment processing, order fulfillment, etc.

In this case, the Facade has encapsulated all the activities and systems related to "order" to provide a single interface – the client remains completely unaware of what happens behind the scenes.

Design Pattern- Facade

4. Strategy 

This design pattern falls under the "Behavioral Design Patterns" type. In the strategy pattern, interchangeable algorithms are encapsulated together in a "family," and one of the algorithms is selected at runtime as needed. For example, a family of algorithms may be related to the "sorting" of products on an e-commerce website based on size, color, award, etc. The strategy is implemented based on customer actions.

This pattern is incredibly powerful in personalized marketing strategies as it responds to customer location, inputs, or actions to provide a different experience to each user.

Design Pattern- Strategy

5. Observer 

The Observer design pattern is of the "Behavioral Design Patterns" type, linking an object (subject) to dependents (observers) in a one-to-many pattern. When any of the observers change, the subject is notified.

The Observer design pattern is useful in any event-driven programming, such as notifying a user of a new comment on Facebook, sending an email when an article is submitted, etc.

Design Pattern- Observer

6. Builder

The Builder design pattern is of the "Creational Design Patterns" type, separating the construction of an object from its representation. This design pattern allows for greater control over the design process (more step-by-step), but also decouples the representation to support multiple representations of an object using the same base construction code (the ConcreteBuilder step).

This pattern executes in sequential steps as the object is built, calling only the necessary steps for each iteration of the object.

Design Pattern- Builder

7. Adapter

The Adapter design pattern is a "wrapper" that converts one interface type into another existing interface type. The Adapter design pattern helps classes work together when they are incompatible, enabling code to function together.

These patterns are useful for taking mixed interfaces and converting them into a consistent API.

Design Pattern- Adapter

EXPERIENCE MAKES THE MASTER

In Software Engineering, there are advantages and disadvantages to using software Design Patterns. Knowing when to use software Design Patterns, and when not to, and understanding the best way to implement each pattern boils down to having an experienced team that can identify each problem and associate it with a solution that each Design Pattern can offer.


Te recomendamos leer...