Design Patterns Basic
Design patterns are easy to learn backwards: memorize the UML diagram first, then hunt for a place to apply it. It is more useful to start from a concrete symptom in the code, then ask which pattern addresses exactly that symptom.
Pick an article by symptom
Section titled “Pick an article by symptom”| Symptom | Pattern | Article |
|---|---|---|
A function keeps growing because every business variant adds another if branch; testing one calculation means building the whole workflow |
Strategy | Strategy pattern |
| The interface the application wants does not match the SDK or provider; their names and states leak into business logic | Adapter | Adapter pattern |
| The same cross-cutting behaviour (cache, retry, metrics) is copy-pasted around many calls | Decorator | Decorator pattern |
| One business event triggers email, points and analytics, and the service keeps importing more modules | Observer / domain event | Observer and domain events |
Reading order
Section titled “Reading order”- Strategy first: isolate what varies (selector, strategy, context), with a NestJS DI example and a comparison with State and Template Method.
- Adapter next: put a translation layer at the integration boundary, connect it to hexagonal ports and adapters and the anti-corruption layer, with an error classification table. This article holds the full
PaymentPortexample.
The two patterns are often used together: one adapter per gateway, one strategy that picks the gateway per merchant.
Read alongside
Section titled “Read alongside”- Choosing test boundaries: isolating variation behind a contract lets each variant be tested independently.
- Bounded context: Adapter is how an anti-corruption layer is implemented at the architecture level.
- Modular monolith and microservices: the same boundary question at a larger scale.