Back
Gang of Four (GoF) Design Patterns - Complete Guide

Gang of Four (GoF) Design Patterns - Complete Guide

The Gang of Four (GoF) design patterns are a collection of 23 classic software design patterns first described in the 1994 book "Design Patterns: Elements of Reusable Object-Oriented Software" by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (hence the name "Gang of Four").

Categories of GoF Design Patterns

The patterns are divided into three main categories:

1. Creational Patterns (5 patterns)

Deal with object creation mechanisms, trying to create objects in a manner suitable to the situation.

2. Structural Patterns (7 patterns)

Concerned with how classes and objects are composed to form larger structures.

3. Behavioral Patterns (11 patterns)

Characterize the ways in which classes or objects interact and distribute responsibility.

Detailed Pattern Descriptions

Creational Patterns

1. Abstract Factory

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

Use when: a system should be independent of how its products are created, composed, and represented.
2. Builder

Separates the construction of a complex object from its representation.

Use when: the algorithm for creating a complex object should be independent of the parts that make up the object.
3. Factory Method

Defines an interface for creating an object, but lets subclasses decide which class to instantiate.

Use when: a class can't anticipate the class of objects it must create.
4. Prototype

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

Use when: the classes to instantiate are specified at runtime.
5. Singleton

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

Use when: exactly one instance of a class is required.

Structural Patterns

6. Adapter (Wrapper)

Converts the interface of a class into another interface clients expect.

Use when: you want to use an existing class, and its interface does not match the one you need.
7. Bridge

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

Use when: you want to avoid a permanent binding between an abstraction and its implementation.
8. Composite

Composes objects into tree structures to represent part-whole hierarchies.

Use when: you want to represent part-whole hierarchies of objects.
9. Decorator

Attaches additional responsibilities to an object dynamically.

Use when: you want to add responsibilities to individual objects dynamically and transparently.
10. Facade

Provides a unified interface to a set of interfaces in a subsystem.

Use when: you want to provide a simple interface to a complex subsystem.
11. Flyweight

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

Use when: an application uses a large number of objects.
12. Proxy

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

Use when: you need a more versatile or sophisticated reference to an object.

Behavioral Patterns

13. Chain of Responsibility

Aviods coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.

Use when: more than one object may handle a request, and the handler isn't known a priori.
14. Command

Encapsulates a request as an object, thereby letting you parameterize clients with different requests.

Use when: you want to parameterize objects by an action to perform.
15. Interpreter

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

Use when: there is a language to interpret.
16. Iterator

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

Use when: you want to access an aggregate object's contents without exposing its internal representation.
17. Mediator

Defines an object that encapsulates how a set of objects interact.

Use when: a set of objects communicate in well-defined but complex ways.
18. Memento

Without violating encapsulation, captures and externalizes an object's internal state so that the object can be restored to this state later.

Use when: a snapshot of an object's state must be saved so that it can be restored to that state later.
19. Observer (Publish-Subscribe)

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

Use when: a change to one object requires changing others.
20. State

Allows an object to alter its behavior when its internal state changes.

Use when: an object's behavior depends on its state.
21. Strategy

Defines a family of algorithms, encapsulates each one, and makes them interchangeable.

Use when: many related classes differ only in their behavior.
22. Template Method

Defines the skeleton of an algorithm in an operation, deferring some steps to subclasses.

Use when: you want to let subclasses redefine certain steps of an algorithm.
23. Visitor

Represents an operation to be performed on the elements of an object structure.

Use when: an object structure contains many classes of objects with differing interfaces.

Benefits of Using GoF Patterns

  • Proven Solutions: Provide tested, proven development paradigms
  • Reusability: Promote code reuse and prevent subtle issues
  • Scalability: Help create flexible designs that are easier to extend
  • Communication: Provide common vocabulary for developers
  • Maintainability: Make code more understandable and maintainable

When to Use Design Patterns

  • When you need to solve a problem that matches a pattern's intent
  • When you want to improve code structure and maintainability
  • When you want to communicate design decisions more clearly
  • When you need to create flexible, reusable components

Criticism and Considerations

While powerful, design patterns should not be overused. Considerations include:

  • Don't force patterns where they don't fit naturally
  • Some patterns may introduce unnecessary complexity in simple scenarios
  • Modern languages and frameworks may provide built-in solutions for some pattern use cases
  • Over-reliance on patterns can lead to over-engineered solutions

The GoF design patterns remain foundational knowledge for software developers, providing a toolkit for solving common design problems in object-oriented systems.

Comments - Beta - WIP

Leave a Comment