DevDocsDev Docs
Design Patterns

Design Patterns

The 24 Gang of Four design patterns with TypeScript examples

Design Patterns

Design patterns are reusable solutions to common problems in software design. The Gang of Four (GoF) defined 23 classic patterns in their book "Design Patterns: Elements of Reusable Object-Oriented Software", plus one additional pattern (Interpreter) is often included.

Pattern Categories

Quick Reference

PatternCategoryPurpose
Factory MethodCreationalCreate objects without specifying exact class
Abstract FactoryCreationalCreate families of related objects
BuilderCreationalConstruct complex objects step by step
PrototypeCreationalClone existing objects
SingletonCreationalEnsure single instance
AdapterStructuralMake incompatible interfaces work together
BridgeStructuralSeparate abstraction from implementation
CompositeStructuralCompose objects into tree structures
DecoratorStructuralAdd responsibilities dynamically
FacadeStructuralProvide simplified interface
FlyweightStructuralShare common state between objects
ProxyStructuralProvide placeholder for another object
Chain of ResponsibilityBehavioralPass request along chain of handlers
CommandBehavioralEncapsulate request as object
InterpreterBehavioralDefine grammar and interpret sentences
IteratorBehavioralTraverse collection without exposing internals
MediatorBehavioralDefine simplified communication
MementoBehavioralCapture and restore object state
ObserverBehavioralNotify dependents of state changes
StateBehavioralAlter behavior when state changes
StrategyBehavioralDefine family of interchangeable algorithms
Template MethodBehavioralDefine skeleton of algorithm
VisitorBehavioralAdd operations without modifying classes

When to Use Design Patterns

TypeScript Considerations

Since TypeScript supports both functional and object-oriented paradigms, many patterns can be implemented in multiple ways:

/**
 * Factory function to create a prefixed logger
 * @description Function-based approach (preferred for simple cases)
 * @param prefix - The prefix to prepend to all log messages
 * @returns A logger object with log and error methods
 */
const createLogger = (prefix: string) => {
  return {
    /** Log an info message with the configured prefix */
    log: (message: string) => console.log(`[${prefix}] ${message}`),
    /** Log an error message with the configured prefix */
    error: (message: string) => console.error(`[${prefix}] ERROR: ${message}`),
  };
};

const logger = createLogger("App");
logger.log("Hello World");
//     ^?

For complex scenarios requiring inheritance or polymorphism, consider the patterns in this documentation. Remember: don't use a pattern just because it exists – use it when it genuinely solves your problem.

On this page