Skip to content

caiodom/how-to-design-patterns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Gang of Four Design Patterns

A simple explanation of the 23 design patterns introduced by the Gang of Four (GoF) in their seminal book "Design Patterns: Elements of Reusable Object-Oriented Software". These patterns are solutions to common problems in software design and are divided into Creational, Structural, and Behavioral categories.

Table of Contents

Introduction

The Gang of Four—Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides—introduced 23 design patterns that provide time-tested solutions to common problems in software design. Understanding these patterns is crucial for designing flexible, maintainable, and robust software systems.

Creational Patterns

Creational patterns focus on the instantiation process of objects, aiming to make a system independent of how its objects are created, composed, and represented.

Abstract Factory

Definition: Provides an interface for creating families of related or dependent objects without specifying their concrete classes.

Why It Matters: It allows for the creation of objects without coupling the code to specific classes, making it easier to introduce new product families without modifying existing code.

Builder

Definition: Separates the construction of a complex object from its representation, allowing the same construction process to create different representations.

Why It Matters: It simplifies the creation of complex objects by breaking down the construction process into simpler steps, promoting code reusability and readability.

Factory Method

Definition: Defines an interface for creating an object but lets subclasses decide which class to instantiate. It lets a class defer instantiation to subclasses.

Why It Matters: It provides a way to encapsulate object creation, promoting loose coupling and greater flexibility in extending code.

Prototype

Definition: Specifies the kinds of objects to create using a prototypical instance and creates new objects by copying this prototype.

Why It Matters: It enables the addition of new object types by cloning existing instances, reducing the need for subclassing and enhancing performance in certain situations.

Singleton

Definition: Ensures a class has only one instance and provides a global point of access to it.

Why It Matters: It controls access to a shared resource, preventing conflicts and inconsistencies that can arise from multiple instances.

Structural Patterns

Structural patterns deal with object composition, aiming to simplify the design by identifying simple ways to realize relationships among entities.

Adapter

Definition: Converts the interface of a class into another interface clients expect, allowing classes to work together that couldn't otherwise due to incompatible interfaces.

Why It Matters: It promotes the reuse of existing classes in new contexts by adapting their interfaces to meet new client expectations.

Bridge

Definition: Decouples an abstraction from its implementation so that the two can vary independently.

Why It Matters: It separates the abstraction from the implementation, allowing them to be developed and modified independently, enhancing flexibility and scalability.

Composite

Definition: Composes objects into tree structures to represent part-whole hierarchies, allowing clients to treat individual objects and compositions uniformly.

Why It Matters: It simplifies client code by allowing complex structures and individual objects to be treated the same way, promoting transparency and ease of use.

Decorator

Definition: Attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Why It Matters: It allows for the addition of behaviors to individual objects without affecting others, promoting code flexibility and reusability.

Facade

Definition: Provides a unified interface to a set of interfaces in a subsystem, making it easier to use.

Why It Matters: It simplifies the usage of complex subsystems by providing a single entry point, reducing dependencies and promoting cleaner code.

Flyweight

Definition: Uses sharing to support large numbers of fine-grained objects efficiently.

Why It Matters: It minimizes memory usage by sharing common parts of objects, which is particularly useful in environments with limited resources.

Proxy

Definition: Provides a surrogate or placeholder for another object to control access to it.

Why It Matters: It adds a level of indirection to support controlled access, lazy initialization, logging, or other functionalities without modifying the original object.

Behavioral Patterns

Behavioral patterns are concerned with algorithms and the assignment of responsibilities between objects, focusing on communication between them.

Chain of Responsibility

Definition: Passes a request along a chain of handlers, allowing multiple objects a chance to handle the request without coupling the sender to a specific receiver.

Why It Matters: It decouples senders and receivers, promoting flexibility in assigning responsibilities and enhancing code maintainability.

Command

Definition: Encapsulates a request as an object, thereby allowing for parameterization of clients with queues, requests, and operations.

Why It Matters: It allows for the decoupling of the object that invokes the operation from the one that knows how to perform it, enabling features like undo/redo operations.

Interpreter

Definition: Given a language, defines a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

Why It Matters: It facilitates the implementation of specialized languages or notations within applications, promoting flexibility and extensibility.

Iterator

Definition: Provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

Why It Matters: It promotes encapsulation and simplifies the traversal of complex data structures, enhancing code readability and maintainability.

Mediator

Definition: Defines an object that encapsulates how a set of objects interact, promoting loose coupling by preventing objects from referring to each other explicitly.

Why It Matters: It centralizes complex communications and control logic between objects, simplifying object interactions and enhancing code reusability.

Memento

Definition: Captures and externalizes an object's internal state without violating encapsulation, so that the object can be restored to this state later.

Why It Matters: It enables undo/redo functionality without exposing the internal structure of objects, preserving encapsulation.

Observer

Definition: Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Why It Matters: It promotes loose coupling between objects, allowing for dynamic relationships and enhancing system scalability.

State

Definition: Allows an object to alter its behavior when its internal state changes, appearing to change its class.

Why It Matters: It simplifies complex conditional logic by encapsulating state-specific behaviors, enhancing code clarity and maintainability.

Strategy

Definition: Defines a family of algorithms, encapsulates each one, and makes them interchangeable, letting the algorithm vary independently from clients that use it.

Why It Matters: It promotes the use of interchangeable algorithms, enhancing flexibility and reuse without modifying client code.

Template Method

Definition: Defines the skeleton of an algorithm in a method, deferring some steps to subclasses.

Why It Matters: It promotes code reuse by allowing subclasses to redefine certain steps without changing the algorithm's structure.

Visitor

Definition: Represents an operation to be performed on elements of an object structure, allowing new operations to be defined without changing the classes of the elements.

Why It Matters: It separates algorithms from the objects on which they operate, promoting flexibility and the ability to add new operations without modifying existing structures.

Conclusion

Understanding and applying the Gang of Four design patterns can significantly enhance the quality of software design. These patterns provide proven solutions to common design problems, promoting code that is robust, maintainable, and scalable.

About

Simple examples showcasing the use of design patterns.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages