What you'll learn
Design patterns are proven, reusable solutions to problems that come up again and again in software design. Learning them gives you a shared vocabulary with other developers and a toolbox of tried-and-tested approaches — so you don't reinvent the wheel.
By the end you'll be able to:
- Explain why patterns matter and how they're categorised
- Apply key creational patterns (Singleton, Factory, Builder)
- Recognise structural patterns (Adapter, Decorator, Facade)
- Use behavioral patterns (Strategy, Observer)
- Know when not to reach for a pattern
The three categories
The classic "Gang of Four" catalogue groups 23 patterns into three families by what they're about. You've already met several without naming them — iterators, the builder-like fluent APIs, and the strategy-like functional interfaces:
Creational
How objects are created
Singleton · Factory · Builder
Structural
How objects are composed
Adapter · Decorator · Facade
Behavioral
How objects interact
Strategy · Observer · Command
Creational patterns
These control how objects are made. Singleton ensures a class has exactly one instance with a global access point — good for shared config or a connection pool:
class Config {
private static final Config INSTANCE = new Config(); // the only one
private Config() { } // block 'new'
public static Config get() { return INSTANCE; }
public String appName() { return "MasterCoding"; }
}
public class Main {
public static void main(String[] args) {
System.out.println(Config.get().appName()); // one shared instance
}
}Factory methods create objects without exposing the exact class (you ask for a "shape" and get the right subclass). Builder constructs a complex object step by step with a readable, fluent API — far nicer than a constructor with ten arguments:
// Builder: construct a complex object step by step, readably
Pizza pizza = new Pizza.Builder()
.size("large")
.addTopping("cheese")
.addTopping("mushroom")
.thinCrust(true)
.build();Structural patterns
These describe how objects are composed into larger structures:
- Adapter — wraps an incompatible interface so it fits what your code expects (a plug adapter)
- Decorator — adds behaviour by wrapping an object, without changing its class (Java's I/O streams are decorators)
- Facade — a simple front door to a complex subsystem
- Proxy — a stand-in that controls access (lazy loading, caching, security)
Behavioral patterns
These govern how objects communicate. Strategy — the most useful — lets you swap an algorithm at runtime by holding it behind an interface. Notice this is exactly what functional interfaces and dependency injection enable:
interface Discount { double apply(double price); }
class NoDiscount implements Discount { public double apply(double p) { return p; } }
class HalfOff implements Discount { public double apply(double p) { return p * 0.5; } }
class Checkout {
private final Discount discount;
Checkout(Discount d) { this.discount = d; } // inject the strategy
double total(double price) { return discount.apply(price); }
}
public class Main {
public static void main(String[] args) {
Checkout sale = new Checkout(new HalfOff()); // swap behaviour freely
System.out.println(sale.total(100));
}
}Observer lets objects subscribe to and react to events (the model behind UI listeners and event systems). Others include Command (wrap an action as an object), State, Template Method, and Iterator (which you used in every for-each loop). At a larger scale, MVC and layered architecture organise whole applications (Module 37).
When NOT to use patterns
Patterns are tools, not goals. Forcing them where they aren't needed adds complexity and hurts readability — the opposite of their purpose. Reach for a pattern when you recognise the problem it solves in your code, not because a pattern exists. A simple method often beats an elaborate pattern.
Watch out
Recap & quick check
Key takeaways
- Design patterns are reusable solutions and a shared vocabulary for common design problems.
- Creational (Singleton, Factory, Builder) control object creation.
- Structural (Adapter, Decorator, Facade) control composition; Java I/O uses Decorator.
- Behavioral (Strategy, Observer, Command) control interaction; Strategy swaps algorithms at runtime.
- Use a pattern only when you recognise the problem it solves — don't force them (KISS).
Quick check
1. The Singleton pattern ensures…
2. Which category does the Builder pattern belong to?
3. What does the Strategy pattern let you do?
4. Java's I/O stream classes are a real-world example of which pattern?
5. When should you apply a design pattern?
Excellent — you've got a professional design toolbox. Next up: Module 35 — Algorithms & Data Structures.