4.2 Architecture Styles And Their Tradeoffs
Architecture is the set of important decisions that are hard to change later. It includes module boundaries, data ownership, communication patterns, deployment shape, failure handling, and team ownership.
Architecture style is useful only when it helps quality attributes.
Common styles
| Style | Strength | Cost |
|---|---|---|
| Layered | Familiar separation between presentation, domain, data | Can become rigid or anemic |
| Client-server | Clear split between client and service | Network, versioning, offline behavior |
| MVC | Separates view, controller, model concerns | Boundaries blur in complex apps |
| Modular monolith | Simple deployment with strong internal boundaries | Requires discipline to avoid becoming a big ball |
| Microservices | Independent deployment and scaling | Distributed systems, observability, data consistency |
| Event-driven | Decouples producers and consumers | Debugging, ordering, eventual consistency |
| Pipe-and-filter | Good for transformations and pipelines | Awkward for shared mutable state |
The style is not the architecture. The real architecture is how the system behaves under change and failure.
Quality attributes drive choice
Choose architecture by asking:
- Where do we need independent change?
- Where do we need strong consistency?
- What must scale independently?
- Which failures must be isolated?
- Which teams own which parts?
- What operational skills do we actually have?
A grounded recommendation
For many product teams, a modular monolith is a strong starting point: one deployable unit, explicit internal boundaries, clear domain modules, contract tests between modules, and a path to extract services later if measured pressure appears.
Microservices are powerful when domain boundaries and operational maturity exist. They are expensive when used to compensate for unclear design.