Introduction to GoF Design Patterns β What They Are, When to Use with GitHub Examples
June 18, 2025
Design patterns are time-tested, battle-hardened solutions to recurring design problems in software engineering. They help you write cleaner, more maintainable, and more scalable code by providing a shared language and best practices for solving architectural and structural challenges.
Whether youβre building APIs, handling business logic, or integrating with third-party services, knowing when and how to apply these patterns can drastically improve your architecture.
π What are Design Patterns?
Design patterns are general reusable solutions to commonly occurring problems in software design. They are not code snippets, but blueprints or templates that guide implementation. The Gang of Four (GoF) Design Patterns refer to a set of 23 classic software design patterns, documented in the highly influential 1994 book Design Patterns: Elements of Reusable Object-Oriented Software.
π§ Why Use Design Patterns?
- β Improve code readability and maintainability
- β Promote reusability and extensibility
- β Enable better communication between engineers using shared terminology
- β Help detect code smells and refactor better
- β Make systems scalable and robust under change
π― This Guide
This guide is a curated list of all 23 GoF design patterns, ordered by real-world backend usefulness and relevance (subjective) in modern industry applications.
Each pattern includes:
- β What it is
- π When to use
- π Link to GitHub implementation
π§© Design Patterns for Backend Developers
1. Strategy (Behavioral)
β
Defines a family of interchangeable algorithms or behaviors and encapsulates each one.
π Use when you have multiple ways to perform a task and want to switch logic at runtime without if-else
or switch
.
π Example β GitHub
2. Observer (Behavioral)
β
Enables a one-to-many dependency so when one object changes state, all dependents are notified.
π Use for implementing event-driven communication (e.g., domain or integration events).
π Example β GitHub
3. Factory Method (Creational)
β
Provides an interface for creating objects, allowing subclasses or context to decide which to instantiate.
π Use when object creation depends on conditions and you want to avoid direct instantiation.
π Example β GitHub
4. Decorator (Structural)
β
Adds behavior to individual objects without changing their structure or affecting others.
π Use to apply logging, caching, or authorization logic dynamically around core functionality.
π Example β GitHub
5. Adapter (Structural)
β
Converts the interface of one class into another expected by the client.
π Use when integrating with third-party APIs or systems that donβt match your internal models.
π Example β GitHub
6. Command (Behavioral)
β
Encapsulates a request as an object, allowing for parameterization and queuing.
π Use for encapsulating operations like audit logging, action queuing, or as part of a CQRS architecture.
π Example β GitHub
7. Singleton (Creational)
β
Ensures a class has only one instance and provides a global access point to it.
π Use for shared configuration, logging, or caching components.
π Example β GitHub
8. Builder (Creational)
β
Builds complex objects step-by-step without using a telescoping constructor (having multiple constructors with increasing parameters).
π Use when creating objects that require many optional or configurable parameters.
π Example β GitHub
9. Proxy (Structural)
β
Acts as a placeholder or surrogate for another object, controlling access.
π Use for lazy loading, access control, rate limiting, etc.
π Example β GitHub
10. Chain of Responsibility (Behavioral)
β
Passes a request along a chain of handlers until one handles it.
π Use to create processing pipelines (e.g., authorization, validation, logging, middleware).
π Example β GitHub
11. Composite (Structural)
β
Treats individual objects and groups uniformly.
π Use when representing tree structures like permissions or organizational units.
π Example β GitHub
12. Template Method (Behavioral)
β
Defines the skeleton of an algorithm, deferring steps to subclasses.
π Use when multiple classes share the same workflow but differ in steps.
π Example β GitHub
13. Facade (Structural)
β
Provides a simplified interface to a complex system.
π Use when exposing simplified operations for external clients or APIs.
π Example β GitHub
14. State (Behavioral)
β
Allows an object to alter its behavior when its internal state changes.
π Use for workflows like order/payment or any other status transitions.
π Example β GitHub
15. Abstract Factory (Creational)
β
Creates families of related or dependent objects without specifying concrete classes.
π Use when you need to provide a family of related components without tightly coupling the client to specific classes.
π Example β GitHub
16. Mediator (Behavioral)
β
Centralizes communication between components to reduce coupling by introducing a central coordinator.
π Use when multiple components interact in complex ways.
π Example β GitHub
17. Bridge (Structural)
β
Decouples abstraction (what is done) from implementation (how it is done).
π Use when you want to avoid tight coupling between logic and its implementation, like logging to different outputs or switching data sources.
π Example β GitHub
18. Flyweight (Structural)
β
Shares data between many fine-grained objects to save memory.
π Use for immutable data reused at scale (e.g., country codes, currency).
π Example β GitHub
19. Prototype (Creational)
β
Creates new objects by cloning existing ones.
π Use for performance optimization, object pools, or similar object copies.
π Example β GitHub
20. Iterator (Behavioral)
β
Provides a way to access elements of a collection sequentially.
π Use to abstract traversal logic from the client (e.g., paged DB results).
π Example β GitHub
21. Memento (Behavioral)
β
Captures and restores an objectβs internal state without violating encapsulation.
π Use for undo/redo functionality, or state snapshots.
π Example β GitHub
22. Interpreter (Behavioral)
β
Defines a way to evaluate grammar or expressions.
π Use for parsing simple DSLs (Domain-Specific Language), rules, or formula logic.
π Example β GitHub
23. Visitor (Behavioral)
β
Lets you add new operations to existing object structures without modifying them.
π Use when you need to perform different operations across a collection of object types without changing their classes. Often an overkill unless youβre operating on complex object structures (like compilers or ASTs).
π Example β GitHub
π Follow & Stay Tuned
Iβll be publishing in-depth articles on selected high-impact patterns with real-world use cases hopefully soon.
π Follow me on LinkedIn for updates.
You can β the GitHub repo if you found this useful!