Code rarely dies from being wrong, it dies from being rigid: one new requirement forces edits in twenty files, and every change makes the next one harder. The same rigidity shows up in the same situations so often that the ways out have names. A design pattern is a reusable solution to a problem that keeps coming up in software design. It isn't code you copy and paste, it's a blueprint for arranging your classes and objects so the design stays flexible as the system grows. The patterns here come from the Gang of Four, who cataloged them in 1994 and sorted them into three families: creational, structural, and behavioral.
Creational patterns deal with how objects get made. Instead of scattering constructor calls and setup logic all over your code, they keep object creation in one flexible place. Five patterns live here, from the everyday Factory Method to the one-and-only Singleton.
Structural patterns are about how objects fit together into something bigger. The goal is to compose flexible systems out of smaller parts without everything turning brittle. There are seven of them. Decorator wraps one object inside another to add behavior, and Facade hides a tangled subsystem behind a single clean interface.
Behavioral patterns are the largest family, ten in all. They handle how objects talk to each other and split up the work, so the pieces stay loosely coupled instead of wired directly together. Observer, Strategy, and State all live here.
Here is the whole catalog, grouped by family. Each pattern will get its own page with diagrams and a code walkthrough soon. For now, use this as a map of how all 22 relate.
Every object starts with a constructor call, and scattering those calls around couples your code to concrete classes. These five decide who runs the constructor and when, from a single overridable factory all the way to a guaranteed lone instance.
Adding a new product type shouldn't mean editing every place that builds one. Subclasses decide what gets created.
Keeps a whole family consistent: ask for the dark theme and every button, menu, and dialog comes back matching.
A constructor with nine arguments is a trap. Build the object step by step, using only the steps you need.
When setup is expensive or hidden, don't rebuild. Clone a working example and adjust the copy.
One instance, guaranteed, reachable from anywhere. The most famous pattern, and the most abused one.
Once objects exist, they have to fit together, and inheritance alone makes the combinations explode. These seven are composition moves instead: wrap to translate or add behavior, share to save memory, and hide whole subsystems behind one front.
Your code expects one interface and the library speaks another. A thin wrapper translates so neither has to change.
Three shapes times four renderers shouldn't cost twelve classes. Split the two dimensions and they vary independently.
A file and a folder of a thousand files answer the same call. One thing and a group of things, treated identically.
Stack behaviors at runtime instead of multiplying subclasses. Wrap the object, add the feature, repeat.
One simple call in front of thirty tangled ones. Callers get a clean entry point and the subsystem keeps its mess private.
A million characters on screen, but only a handful of fonts. Share what repeats and memory stops exploding.
A stand-in with the same interface as the real thing, free to lazy-load, cache, or guard before passing the call through.
Built and wired together, objects still have to talk without hard-coding who calls whom. These ten separate the asker from the answerer, whether the thing in motion is a request, an algorithm, a state change, or an undo.
Nobody has to know who will handle the request. Each handler either takes it or passes it down the line.
Once a request is an object, you can queue it, log it, and reverse it. Every undo stack is built on this.
Loop over a tree, a list, or a graph with the same code. The collection keeps its insides to itself.
Ten objects talking directly means 45 connections. Route everything through one hub and they stop knowing each other.
Snapshots an object's private state without exposing it. Undo works because someone saved one of these.
One change triggers many reactions without any hard wiring. Subscribers sign up and get notified the moment something happens.
An object that acts like a different object in each state, without a giant switch statement in sight.
Swap the algorithm without touching the code that calls it. Sorting, pricing, and routing rules become plug-ins.
When five algorithms share one outline, write the outline once. Subclasses fill in only the steps that differ.
New operations on a stable family of classes, added without touching a single one of them.