2.1 Top-Down vs. Bottom-Up
When faced with designing a system's architecture, architects generally follow one of two broad strategies — or, most commonly, a blend of both.
Top-Down Design
Start from the overall system and decompose into smaller parts. You begin with the big picture — the system boundary, its major responsibilities, the external systems it interacts with — and progressively break it down into subsystems, components, and modules.
Top-down works well when you have a clear understanding of the domain and the requirements are reasonably well-known. It's the natural approach for greenfield projects where you're starting from scratch.
Bottom-Up Design
Start from known building blocks and compose them into a larger system. You begin with existing components, libraries, services, or legacy systems and figure out how to combine them into a coherent whole.
Bottom-up is common in brownfield projects — where you're modernizing an existing system, integrating legacy components, or building on top of established platforms. You're constrained by what already exists.
Mixed / Iterative Approach
In practice, most architects use both approaches simultaneously. You sketch the top-level structure (top-down), then validate it against known components and constraints (bottom-up), and iterate. This "meet in the middle" strategy is the most realistic approach for real-world projects.
| Approach | Starting Point | Best For | Risk |
|---|---|---|---|
| Top-Down | System as a whole | Greenfield, well-understood domains | May ignore technical realities |
| Bottom-Up | Existing components | Brownfield, legacy modernization | May lack coherent overall structure |
| Mixed | Both — iterate | Most real-world projects | Requires discipline to converge |
2.2 Decomposition and Modularization
Decomposition is the act of breaking a complex system into smaller, manageable pieces. It's the most fundamental technique in software architecture — and arguably in all of engineering. The question is: how do you decide where to draw the boundaries?
Why Decompose?
- Manage complexity — Humans can only hold so much in their heads at once. Smaller pieces are easier to understand.
- Enable parallel development — Independent teams can work on different building blocks simultaneously.
- Support independent deployment — Well-decomposed systems allow deploying parts independently (critical for microservices).
- Improve maintainability — Changes in one area shouldn't require changes everywhere else.
- Enable reuse — Well-defined building blocks with clean interfaces can be reused across projects.
Decomposition Criteria
There is no single "correct" way to decompose a system. The criteria you use depend on your context, priorities, and constraints:
Domain-based decomposition is generally preferred for business applications because it aligns the system structure with the business structure. When a business capability changes, only the corresponding building block needs to change. This is the central idea behind Domain-Driven Design.
Technical decomposition (layers) is simpler to understand but tends to cause problems at scale: a single business change may require modifications across all layers (UI, logic, data), leading to high coordination overhead.
2.3 Conway's Law
"Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations."
— Melvin Conway, 1967
This is not just an observation — it's a force of nature in software engineering. If your organization has a frontend team, a backend team, and a database team, your system will naturally end up with a frontend layer, a backend layer, and a database layer — regardless of whether that's the best architecture for the problem.
Conway's Law has profound implications for architects:
- Your architecture is constrained by your org structure whether you plan for it or not
- If you want to change your architecture, you may need to change your team structure first
- Cross-team interfaces will become the most important (and most fragile) parts of your system
The Inverse Conway Maneuver
Instead of letting your org structure accidentally shape your architecture, deliberately design your team structure to produce the architecture you want. This is called the Inverse Conway Maneuver.
For example, if you want a microservices architecture with independent services for "Orders," "Payments," and "Inventory," create teams aligned to those domains — not teams aligned to technical layers.
Domain-Driven Design (DDD) — Going Deeper
The CPSA-F curriculum mentions DDD briefly, but it's become one of the most influential approaches to architecture design, especially for microservices. Key DDD concepts:
Bounded Contexts
A bounded context is a clear boundary within which a particular domain model is defined and applicable. Inside the boundary, terms have specific meanings. Different bounded contexts can use the same word to mean different things — and that's OK.
For example, "Customer" in the Sales context might include purchase history and preferences, while "Customer" in the Shipping context might only include name and address. These are two different models with the same name.
Ubiquitous Language
Within a bounded context, everyone — developers, domain experts, testers — uses the same language to describe concepts. This language is used in conversations, documentation, and code. If the code says Order, the business says "Order," not "Purchase Request."
Context Mapping
When bounded contexts need to interact, you define explicit relationships between them:
- Partnership — Two teams cooperate closely, evolving their models together
- Customer-Supplier — Upstream team provides what downstream team needs
- Conformist — Downstream team adopts the upstream model as-is
- Anti-Corruption Layer (ACL) — Downstream team translates the upstream model into its own model
- Shared Kernel — Two contexts share a small, explicitly managed model subset
Context mapping is critical for microservices architectures because it determines how services communicate and evolve independently.
Summary
| Concept | Key Takeaway |
|---|---|
| Top-down | Decompose from the whole — good for greenfield |
| Bottom-up | Compose from parts — good for brownfield/legacy |
| Mixed | Most common in practice — iterate between both |
| Decomposition | Goal: high cohesion, low coupling — domain-based is generally preferred |
| Conway's Law | System structure mirrors org structure — plan for it |
| DDD | Bounded contexts, ubiquitous language, context mapping |