Design Patterns Introduction
What design patterns are, the three Gang of Four categories, and how to use patterns without over-engineering.
What are design patterns?
A design pattern is a proven, reusable solution to a problem that keeps coming up in software design. It isn't a library you install or code you copy — it's a template for structuring classes and objects that you adapt to your situation.
Patterns give developers a shared vocabulary. Saying "let's put an adapter in front of the payment SDK" or "notifications use the observer pattern" communicates a whole design in a few words — in code reviews, design discussions and interviews.
Where they come from
The classic catalogue is the 1994 book Design Patterns: Elements of Reusable Object-Oriented Software by Gamma, Helm, Johnson and Vlissides — the Gang of Four (GoF). It described 23 patterns in three categories:
| Category | Concerned with | Patterns covered in this tutorial |
|---|---|---|
| Creational | How objects are created | Factory Method, Abstract Factory, Builder, Singleton |
| Structural | How objects are composed into larger structures | Adapter, Decorator, Facade, Proxy, Composite |
| Behavioral | How objects communicate and share responsibilities | Strategy, Observer, Command, State, Template Method |
Patterns you already use
You've probably used patterns without naming them:
| You've seen… | Pattern |
|---|---|
| Laravel/Express middleware wrapping a request handler | Decorator / Chain of Responsibility |
DB::table(), Cache::get() facades in Laravel |
Facade |
Event listeners, addEventListener, Django signals |
Observer |
sorted(items, key=...) — passing behaviour as a function |
Strategy |
| A database connection pool shared across the app | Singleton-like shared instance |
Iterator in Python for loops and Java collections |
Iterator |
Queue jobs (dispatch(new SendEmail(...))) |
Command |
ORM query builders (User::where(...)->orderBy(...)->get()) |
Builder |
The principles behind patterns
Most patterns apply a few deeper ideas:
- Program to an interface, not an implementation — depend on what something does, not what it is.
- Favour composition over inheritance — build behaviour by combining objects instead of deep class hierarchies.
- Encapsulate what varies — isolate the parts likely to change behind a stable interface.
- SOLID — five principles for maintainable object-oriented design (next lesson).
Patterns in Python vs Java
Many GoF patterns were designed for languages like C++ and Java. In Python (and JavaScript, PHP with closures), some become simpler:
- Strategy and Command are often just functions.
- Iterator is built in with generators.
- Decorator has dedicated
@decoratorsyntax (a related but simpler idea). - Singleton is often just a module-level object.
The intent of the pattern stays the same — only the amount of code changes. This tutorial shows idiomatic Python versions, and the ideas transfer directly to Java, PHP, C# and TypeScript.
How to use patterns well
- Start with the problem, not the pattern. Write simple code first; introduce a pattern when duplication or rigid code appears.
- Name it in code and comments (
PaymentGatewayAdapter) so readers recognise it. - Keep it small — a pattern should remove complexity, not add layers.
- Refactor towards patterns as requirements change, instead of predicting every future need.
Anti-patterns to recognise
An anti-pattern is a common "solution" that causes more problems than it solves:
| Anti-pattern | Problem |
|---|---|
| God object | One class knows and does everything |
| Spaghetti code | Tangled control flow with no structure |
| Golden hammer | Using one favourite pattern/tool for every problem |
| Premature abstraction | Interfaces and factories for things that never vary |
| Singleton abuse | Hidden global state that makes testing hard |
Common mistakes
- Pattern-hunting — forcing patterns into code to look sophisticated.
- Copying Java-style boilerplate into Python when a function would do.
- Learning UML diagrams but not the problem each pattern solves.
Key takeaways
- Design patterns are reusable solutions and a shared vocabulary for design problems.
- The GoF catalogue groups them into creational, structural and behavioral patterns.
- They rest on principles: program to interfaces, composition over inheritance, encapsulate what varies.
- Use patterns to remove complexity, never to add it.