Design Patterns
A pattern is a named solution to a recurring design problem. Useful as a vocabulary; dangerous as a shopping list. Apply only when the cost of not applying is concrete.
Why patterns exist
Software has shapes that repeat: "I need to create an object whose concrete class is decided at runtime", "I need to apply an operation across a tree", "I need a single shared resource". Naming these shapes lets two engineers say a word and skip thirty minutes of whiteboarding.
Creational
- Factory Method — defer instantiation to a method that subclasses override. Use when "the right concrete class" depends on context (DB driver, payment processor).
- Abstract Factory — a factory of factories. Used when whole families of related objects vary together (UI toolkit per OS).
- Builder — step-by-step construction of complex objects. Useful when the constructor would take twelve parameters.
- Singleton — exactly one instance. Often abused; usually a hidden global. Prefer dependency injection.
- Prototype — clone an existing object instead of constructing one.
Structural
- Adapter — make an incompatible interface look like the one you expect. The "glue" pattern.
- Decorator — add behaviour to an object at runtime without modifying its class. The basis of middleware stacks.
- Facade — a simpler interface in front of a complex subsystem.
- Composite — treat individual objects and compositions uniformly (tree structures: files/folders, DOM nodes).
- Proxy — a stand-in that adds lazy-loading, caching, or access control.
Behavioural
- Strategy — interchangeable algorithms behind a common interface.
Replaces a chain of
if/elifs. - Observer — a subject notifies subscribers when state changes. Foundation of event systems and reactive UIs.
- Command — wrap an action as an object so it can be queued, logged, undone.
- Iterator — sequential access to a collection without exposing its internals.
- Template Method — a skeleton algorithm with overridable steps.
- State — change object behaviour by swapping a state object.
- Chain of Responsibility — pass a request along a chain until someone handles it (middleware, exception handlers).
How to actually apply them
The wrong question: "where can I apply Decorator?" The right question: "this method has a chain of orthogonal behaviours bolted on with flags — is Decorator the cleanest fix?" Patterns earn their place by removing duplication or coupling. If introducing the pattern adds files without removing duplication, the pattern is the wrong tool.
Code smells (Topic 4) tell you when a pattern is missing. Patterns tell you what to try. Don't drive from the patterns — drive from the smell.
What to remember at exam time
- Three families: creational, structural, behavioural. Place each pattern in one.
- For each, one sentence: "replaces what?" and "common example?".
- Singleton is a code smell unless tightly justified.
- Strategy vs State: same shape, different intent. Strategy = swap algorithm; State = swap behaviour because the object's state changed.