Module 2: Architecture Patterns & Modularity: Worked Examples
Example 1: Recover Boundaries in a Layered Monolith
Problem. OrderService imports inventory repositories, payment SDK types, email templates, and shipment tables. Changes ripple across layers.
Wrong attempt. Split every class into a service. Network boundaries preserve the coupling and add latency, retries, deployment coordination, and partial failure.
Correct reasoning. First form modules around business capabilities: ordering, inventory, payment, and fulfillment. Give each module an API, hide its persistence, prohibit cross-module table access, and enforce dependency rules in CI. Keep the deployment monolithic until independent scaling or delivery evidence pays for distribution.
Example 2: Calculate the Microservice Tax
For a proposed extraction, list added ownership, deployment, observability, security, data-consistency, testing, and on-call costs. If the only benefit is a smaller repository, the extraction fails. If payment requires independent compliance controls and release cadence, the boundary may pay.
Decision rule. Distribution is a consequence of a justified boundary and operational need, not a method for discovering boundaries.
Example 3: Choose a Pattern From Forces
A batch analytics pipeline needs independent stages, replay, and backpressure: pipes-and-filters or event-driven flow fits. A transactional admin application needs simple change and strong consistency: a modular monolith fits. Name the forces and failure modes before naming the pattern.
Completion Standard
- Produce an enforceable module dependency map.
- Write a quantified distribution-tax ledger.
- Compare at least three patterns against the same quality scenarios.