← Back to Blog
ENGINEERING

Design Patterns Guide: The 10 Most Used Software Design Patterns

F. Çağrı BilgehanJanuary 30, 202613 min read
design patternsoopsoftware developmentarchitecture

Design Patterns Guide: The 10 Most Used Software Design Patterns

Design patterns are proven solutions in the software world. Cataloged by the Gang of Four (GoF) in 1994, these patterns remain fundamental to modern software development.

What Is a Design Pattern?

A design pattern is a reusable, proven solution to commonly occurring problems in software design. It's not ready-made code, but a solution template.

Three Categories

| Category | Purpose | Examples | |----------|---------|----------| | Creational | Object creation | Factory, Singleton, Builder | | Structural | Object composition | Adapter, Decorator, Facade | | Behavioral | Object behavior | Observer, Strategy, Command |

Creational Patterns

1. Factory Method

Delegates object creation logic to subclasses:

interface Notification {
  send(message: string): void;
}

class EmailNotification implements Notification {
  send(message: string) { /* send email */ }
}

class SMSNotification implements Notification {
  send(message: string) { /* send SMS */ }
}

function createNotification(type: string): Notification {
  switch(type) {
    case 'email': return new EmailNotification();
    case 'sms': return new SMSNotification();
    default: throw new Error('Unknown type');
  }
}

2. Singleton

Guarantees only one instance of a class exists:

class DatabaseConnection {
  private static instance: DatabaseConnection;
  private constructor() {}

  static getInstance(): DatabaseConnection {
    if (!DatabaseConnection.instance) {
      DatabaseConnection.instance = new DatabaseConnection();
    }
    return DatabaseConnection.instance;
  }
}

3. Builder

Constructs complex objects step by step:

const order = new OrderBuilder()
  .setCustomer('Alice')
  .addItem('Laptop', 1500)
  .addItem('Mouse', 20)
  .setShipping('express')
  .build();

Structural Patterns

4. Adapter

Makes incompatible interfaces work together:

class OldPaymentSystem {
  processPayment(amount: number) { /* ... */ }
}

interface ModernPayment {
  pay(amount: number, currency: string): Promise<boolean>;
}

class PaymentAdapter implements ModernPayment {
  constructor(private oldSystem: OldPaymentSystem) {}
  async pay(amount: number, currency: string) {
    this.oldSystem.processPayment(amount);
    return true;
  }
}

5. Decorator

Adds new behaviors to existing objects dynamically.

6. Facade

Hides complex subsystems behind a simple interface:

class OrderFacade {
  async placeOrder(cart: Cart) {
    await inventory.reserve(cart.items);
    const payment = await paymentService.charge(cart.total);
    await shippingService.schedule(cart.address);
    await notificationService.sendConfirmation(cart.customer);
    return { orderId: generateId(), payment, status: 'confirmed' };
  }
}

Behavioral Patterns

7. Observer

Automatically notifies subscribed objects of changes in another object.

8. Strategy

Makes algorithms interchangeable (swappable):

interface SortStrategy {
  sort(data: number[]): number[];
}

class Sorter {
  constructor(private strategy: SortStrategy) {}
  execute(data: number[]) { return this.strategy.sort(data); }
}

9. Command

Encapsulates requests as objects, enabling undo/redo functionality.

10. Template Method

Defines the skeleton of an algorithm, deferring details to subclasses.

Which Pattern When?

| Problem | Pattern | |---------|---------| | Creating different object types | Factory | | Single instance needed | Singleton | | Build complex objects step by step | Builder | | Connect incompatible interfaces | Adapter | | Add features dynamically | Decorator | | Hide complexity | Facade | | React to changes | Observer | | Swap algorithms | Strategy |

Conclusion

Design patterns are a tool, not a goal. Overusing them is just as harmful as not using them at all. Apply the right pattern to the right problem.

Practice design patterns interactively on the Foundation career path at LabLudus.

Related Posts

What Is Clean Code? 10 Golden Rules for Writing Better Software

Clean Code principles explained: Robert C. Martin's philosophy, SOLID principles, and practical examples for writing maintainable, readable software.

What Is Software Testing? Test Types and Best Practices

Software testing explained: unit tests, integration tests, E2E tests, the test pyramid, TDD, and best practices for writing reliable tests.