DEV Community

Nishchya Verma
Nishchya Verma

Posted on

5 Must-Know Design Patterns Every Developer Should Master

Top 5 Design Patterns
At some point in our careers we’ve all been tangled in if-else nests and duct-taped functions just trying to make things work. But what if I told you there’s a better way? A way used by seasoned developers to write cleaner, smarter, and more maintainable code?

We’ve all heard the term “design patterns” thrown around — usually by that one senior dev who speaks fluent Lorem ipsum.
Maybe you’ve even noticed how certain built-in functions or framework methods just make sense — like they were crafted with some secret blueprint. Well, spoiler alert: they were. That blueprint is what we call a design pattern — a time-tested solution to a common software design problem. In this article, I'll break down the Top 5 Design Patterns you’ve probably seen in the wild (even if you didn’t know their names), and show you how to use them like a pro.

1. Strategy Pattern

Intent: Define a family of algorithms, encapsulate each one, and make them interchangeable.

Use When:

  • You have multiple ways of doing something (e.g., sorting, payment, compression).

  • You want to switch algorithms at runtime.

Structure:

  • Strategy Interface

  • Concrete Strategies

  • Context (uses Strategy)

Sample Code

// Strategy
interface PaymentStrategy {
    void pay(int amount);
}

// Concrete Strategy
class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " using credit card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " using PayPal");
    }
}

// Context
class ShoppingCart {
    private PaymentStrategy strategy;

    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void checkout(int amount) {
        strategy.pay(amount);
    }
}

Enter fullscreen mode Exit fullscreen mode

2. Observer Pattern

Intent: Define a one-to-many dependency so when one object (subject) changes state, all its dependents (observers) are notified.

Use When:

  • An object changes state and others need to know.

  • For event-driven systems (e.g., UI, stock price updates).

Structure:

  • Subject

  • Observer Interface

  • Concrete Observers

Sample Code

interface Observer {
    void update(String message);
}

class EmailSubscriber implements Observer {
    public void update(String message) {
        System.out.println("Email received: " + message);
    }
}

class Publisher {
    private List<Observer> observers = new ArrayList<>();

    public void subscribe(Observer obs) {
        observers.add(obs);
    }

    public void notifyObservers(String message) {
        for (Observer obs : observers) {
            obs.update(message);
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

3. Decorator Pattern

Intent: Attach additional responsibilities to an object dynamically. It’s like wrapping an object with extra behavior.

Use When:

  • You want to add features without changing the base class.

  • Avoid subclass explosion.

Structure:

  • Component Interface

  • Concrete Component

  • Decorator (implements component and wraps another)

Sample Code

interface Coffee {
    String getDescription();
    int cost();
}

class BasicCoffee implements Coffee {
    public String getDescription() { return "Basic Coffee"; }
    public int cost() { return 50; }
}

class MilkDecorator implements Coffee {
    private Coffee coffee;
    public MilkDecorator(Coffee coffee) { this.coffee = coffee; }

    public String getDescription() {
        return coffee.getDescription() + ", Milk";
    }
    public int cost() {
        return coffee.cost() + 10;
    }
}

Enter fullscreen mode Exit fullscreen mode

4. Factory Pattern

Intent: Create objects without exposing the instantiation logic to the client. Use a method to create the object.

Use When:

  • You want to delegate object creation to a separate method/class.

  • Need to avoid tight coupling.

Structure:

  • Interface or Superclass

  • Factory method to create instances

Sample Code

interface Animal {
    void speak();
}

class Dog implements Animal {
    public void speak() {
        System.out.println("Woof!");
    }
}

class AnimalFactory {
    public static Animal getAnimal(String type) {
        if (type.equals("dog")) return new Dog();
        throw new IllegalArgumentException("Unknown type");
    }
}

Enter fullscreen mode Exit fullscreen mode

5. Singleton Pattern

Intent: Ensure a class has only one instance and provide a global access point to it.

Use When:

  • You need only one instance (e.g., DB connection, config).

  • To coordinate actions across the system.

Structure:

  • Private constructor

  • Static instance variable

  • Public static getter method

Sample Code

class ConfigManager {
    private static ConfigManager instance;

    private ConfigManager() {}

    public static ConfigManager getInstance() {
        if (instance == null) {
            instance = new ConfigManager();
        }
        return instance;
    }
}

Enter fullscreen mode Exit fullscreen mode

Thread Safe Version:

public class ThreadSafeSingleton {
    private static final ThreadSafeSingleton instance = new ThreadSafeSingleton();

    private ThreadSafeSingleton() {}

    public static ThreadSafeSingleton getInstance() {
        return instance;
    }
}

Enter fullscreen mode Exit fullscreen mode

Here’s a quick table to help you map the purpose of each pattern to its core concept.

Pattern Purpose Key Concept
Strategy Swap behavior like changing themes Algorithms packed neatly in separate boxes
Observer Alert everyone when something changes One-to-many notification chain
Decorator Add features without changing the original object Wrap it, stack it, reuse it
Factory Don’t new up stuff everywhere One method to create them all
Singleton Only one allowed in the club One instance, globally accessed

So whether you’re building a game, an API, or the next unicorn startup from your garage, these patterns will save you time, headaches, and therapy bills.

Top comments (0)