Behavioral Patterns
Observer, Strategy, State, patterns for runtime behavior
Observer
Spot the polling-loop smell, implement subscribe/notify/unsubscribe on a class, and trace the lapsed listener leak that makes forgotten detach calls eat memory silently.
Strategy
Recognize the 'growing switch on type' smell, extract each branch into a swappable algorithm object or lambda, and spot the same shape inside `Array.sort`, Python `sorted(key=…)`, and Java `Comparator`.
State
Rotate the multi-method `switch(mode)` matrix into one class per mode, push transition decisions onto the modes themselves, and trace the silent-failure shape where the host re-grows an `instanceof` ladder before delegating.
Command
Freeze each button-handler call into an object holding its own `execute` and `undo`, watch the same list of objects become an undo stack or a job queue when you swap the consumer, and spot the shape in Java `Runnable`, Swing `AbstractAction`, Redux actions, and Celery or BullMQ job queues.
Chain of Responsibility
Pull each `if` from `checkAccess` into a one-method class holding one `next` reference, watch a request walk the chain choosing handle/pass/mutate-pass at every box, and spot the same shape in Express middleware, ASP.NET pipelines, Servlet filters, Python `try/except`, and DOM event bubbling.
Mediator
Collapse N(N-1) peer imports into one central coordinator that holds the rules, watch the same shape inside MVC controllers, MediatR's `_sender.Send`, and `useReducer`'s `dispatch`, and recognize when the hub drifts toward a god object.
Structural Patterns
Decorator, Adapter, Facade, Proxy, patterns for combining objects
Decorator
Trade a 2^N subclass table for N wrappers that share one interface, stack compression and encryption around a file source in any order, and spot the same nesting in `new BufferedReader(new FileReader(f))` and Python's `open()`.
Composite
Collapse a recursive `if isinstance(node, Folder)` into one `size()` that both files and folders answer, watch the type check leave the caller and become recursion on the container, and weigh the transparency-versus-safety cost of putting `add()` on every node.
Adapter
Wrap a vendor's `dispatch(to, body, opts)` so two hundred call sites keep calling `send(msg)`, watch the translation live entirely inside the wrapper, and tell it from a decorator by the one thing that differs: the interface changes, not the behaviour.
Proxy
Front an expensive or guarded object with a same-interface stand-in that decides when to create it, whether to allow the call, or whether a cached answer is enough, and spot the shape in JS `new Proxy`, ORM lazy loads, and gRPC stubs.
Facade
Route a handler's five service calls through one method so callers depend on one class instead of five, reach past it straight to a worker for the rare case the method skips, and split the front before it bloats into a god object.
Creational Patterns
Factory, Builder, Singleton, patterns for object creation
Factory Method
Move the `new` behind one overridable method, so a subclass decides which class gets built and callers depend only on the shared type.
Abstract Factory
Group a family of related products behind one factory object, so a single startup choice swaps the whole set and a mismatched combination can never compile.
Builder
Replace a positional constructor with an object that collects named steps and a closing build() call, so every value is labeled where you read it, validation runs before the object exists, and the same step sequence can assemble different products.
Singleton
Separate the two promises Singleton bundles, one instance and a global access point, so you keep the single object but hand it in through constructors instead of a static getter that nothing declares.
Patterns in Practice
Beyond the catalog
Dependency Injection
Spot the class that builds its own collaborators with new, move that construction up into a constructor parameter so the same class turns testable with a fake and swappable in production, and tell true injection apart from a service locator that only looks like it.
Template Method
Extract the shared skeleton of two near-identical methods into a parent that calls overridable steps by name, recognize the same fixed-order shape in framework lifecycle hooks like a test runner's setUp/tearDown, and tell it apart from the run-time version you inject instead of inherit.
Iterator
Pull a loop's index out into a separate cursor that answers next and hasNext, read the same protocol across Python's StopIteration, JavaScript generators, Java's hasNext, and Rust's Option, and tell an iterable apart from the one-pass iterator it hands you.
Anti-Patterns & When Not to Use
Weigh a pattern's up-front indirection against the flexibility it only repays when real variation arrives, name the three ways that bet goes wrong (an abstraction built too early, one bent with a flag per case, a favourite pattern swung at every problem), and wait for the rule of three before you abstract.