← Back to Programming

Design patterns

Design patterns are proven, named solutions to recurring design problems. The 1994 'Gang of Four' book catalogued 23 of them, and their names are now a shared vocabulary among developers.

What patterns are

A design pattern describes a problem, a solution structure, and its trade-offs; it is a template, not finished code. The book Design Patterns: Elements of Reusable Object-Oriented Software (1994), by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, the 'Gang of Four', grouped patterns as creational, structural, and behavioural.

Creational: factory and builder

Factory methods hide which concrete class is created: ShapeFactory.create("circle") returns a Shape without callers needing to know Circle exists. The builder pattern constructs complex objects step by step, avoiding constructors with many confusing parameters: new Pizza.Builder().size(12).cheese().mushrooms().build().

Creational: singleton

A singleton ensures a class has only one instance with a global access point, such as one configuration manager. It is easy to misuse: singletons are effectively global variables, hide dependencies, and make testing harder. Many teams prefer creating one instance and injecting it.

Structural: adapter and decorator

An adapter converts one interface into another that clients expect, like a travel plug adapter, letting an old library work with new code. A decorator wraps an object to add behaviour without changing its class: Java's BufferedReader wraps a FileReader to add buffering, and decorators can be stacked.

Structural: facade and composite

A facade provides one simple interface to a complicated subsystem, such as a single VideoConverter.convert method hiding codecs, buffers, and file formats. Composite lets individual objects and groups be treated the same way: a folder and a file both answer getSize(), with a folder summing its children.

Behavioural: strategy and observer

Strategy defines a family of interchangeable algorithms behind an interface, such as different shipping-cost calculators chosen at run time. Observer lets objects subscribe to events from a subject and be notified automatically when it changes; it underlies event listeners in user interfaces and publish-subscribe systems.

Behavioural: command and iterator

Command wraps a request as an object, making it possible to queue, log, or undo actions: each editor action becomes a Command with execute and undo methods. Iterator provides a standard way to step through a collection without exposing its structure, built into Java's for-each loop and Python's for loop.

Worked example

A checkout calculates shipping by courier. Strategy: interface ShippingStrategy { double cost(Order o); } with StandardShipping (5 dollars flat) and ExpressShipping (10 dollars plus 1 dollar per kilogram). For a 3-kilogram order, standard costs 5 dollars and express 13. Checkout holds a ShippingStrategy and calls cost(); adding overnight shipping needs only a new class.

Key takeaways

Design patterns are named, reusable solution templates; the 1994 Gang of Four book catalogued 23 in creational, structural, and behavioural groups. Factory and builder manage object creation; singleton is often overused. Adapter converts interfaces; decorator adds behaviour by wrapping; facade simplifies subsystems; composite treats parts and wholes alike. Strategy swaps algorithms; observer notifies subscribers; command encapsulates actions for undo; iterator steps through collections. Use patterns where they fit, not everywhere.

Flashcard

Design pattern

Named, reusable solution to a recurring problem

Template, not code.

Check your understanding

A text editor needs undo and redo for every action. Which pattern fits best?

← Previous lesson Next lesson →