Skip to content

VOL 06 / CH 03 / LESSON 02

3.2 Architecture Views, Quality Trade-offs, and Decision Records ​

Architecture decisions shape system structure, quality attributes, and the cost of later changes. Neatly arranged boxes still need an explanation of responsibility and recovery. The purpose of architectural documentation is to enable different stakeholders to see the views that align with their concerns and to understand why those decisions were made.

Start from Architectural Requirements ​

Not every requirement impacts the architecture. Prioritize requirements such as:

  • Features that define system boundaries or assign primary responsibilities;
  • Critical quality attributes such as availability, performance, security, and compliance;
  • Technical or organizational constraints that cannot be easily modified;
  • Decisions involving high risk, significant uncertainty, or high cost of change.

For example, the color of a "registration page button" generally does not affect the architecture; in contrast, a requirement that "payment confirmation must be auditable and cannot be duplicated due to message retransmission" directly influences the data model, idempotency strategies, and system boundaries.

C4: Explain Static Structure at Different Levels of Abstraction ​

The core static structure diagram in C4 has four layers: System Context, Container, Component, and Code. Here, "Container" does not specifically refer to Docker containers; it represents a runtime boundary around executing code or stored data, such as an application, database, or storage bucket. Physical deployment is a separate concern.

LayerQuestions AnsweredPrimary Audience
System ContextWho uses the system, and which external systems does it interact with?All stakeholders
ContainerWhich applications and data stores make up the system, and how do they communicate?Technical staff and relevant business partners
ComponentWhat are the primary responsibilities within a container?Development teams
CodeHow do components map to classes, interfaces, or modules?Implementation engineers

It's not necessary to draw all four layers for completeness. According to the official C4 guidance, the System Context and Container layers are often sufficient for most teams. Component and Code layers should only be included when they help answer real-world questions.

These text sketches help inspect actors and relationships; they are not complete UML documents or input for a diagramming tool. A tournament-management System Context view might look like this:

text
[Participant] ----> [Tournament System] via "Register/Cancel/Check Schedule"
[Administrator] ----> [Tournament System] via "Create Event/Make Judgments/Audit"
[Tournament System] ----> [Payment Platform] via "Request Payments/Refunds"
[Tournament System] ----> [Messaging Provider] via "Send Notifications"

Only after moving into the Container view do we begin to explore internal components:

text
[Web Application] --HTTPS/JSON--> [Business Application]
[Business Application] --SQL--> [Relational Database]
[Business Application] --publish--> [Message Broker]
[Message Broker] --event delivery--> [Notification Worker]
[Notification Worker] --HTTPS--> [Messaging Provider]

Each box should clearly indicate its name, type/technology, and responsibility. Each relationship must specify direction, purpose, and protocol. Without semantic context (just arrows) readers cannot determine whether a connection represents a synchronous call, an asynchronous event, or a data dependency.

UML: Choose Diagrams by Problem, Not by Checklist ​

UML is a standardized modeling language, but it doesn't require every project to use all its diagrams. Common choices include:

  • Class diagrams: domain structure, key relationships, and static dependencies;
  • Sequence diagrams: call order in a specific scenario, boundary interactions, and failure paths;
  • State machine diagrams: entity lifecycle and valid transitions;
  • Deployment diagrams: mapping of runtime nodes to artifacts.

State machine diagrams are particularly well-suited for registration workflows:

text
PENDING --payment successful--> CONFIRMED
PENDING --timeout-------------> EXPIRED
CONFIRMED --user cancels--> CANCELLED
CONFIRMED --event ends----> COMPLETED

Separate edges show that EXPIRED follows PENDING and COMPLETED follows CONFIRMED. If timeout wins the transition from PENDING to EXPIRED, a late payment message cannot blindly overwrite the state with CONFIRMED. Define refund, reconciliation, or reinstatement rules. Expected-state and version checks can protect concurrent transitions, but the diagram supplies no atomicity by itself.

This diagram is still incomplete: the team must clearly define how to handle repeated events, invalid transitions, and concurrent transitions. The value of a diagram lies in surfacing questions; it should not replace written contracts.

Sequence diagrams should include critical failure paths, rather than the "happy path alone." For example, if a database write fails after a successful payment, the recovery strategy (whether through callback retries, reconciliation tasks, or manual intervention) directly impacts consistency design.

4+1: Organizing Views by Stakeholder Concerns ​

Kruchten's 4+1 model describes architecture using multiple parallel views:

ViewFocus
LogicalKey functional design elements and their relationships
ProcessRuntime processes, concurrency, communication, and synchronization
DevelopmentSource code modules, subsystems, and development organizations
PhysicalMapping of software to hardware or runtime nodes
Scenarios (+1)Use critical use cases to drive and validate the other views

C4 is not a one-to-one replacement for the 4+1 model. C4 primarily offers a hierarchical structure for expressing system designs, while 4+1 emphasizes different points of concern. A project can use a C4 Container diagram to explain static components, a sequence diagram to illustrate process interactions, and a deployment diagram to represent the physical view.

Architecture Diagrams Must Be Bounded by Quality Attributes ​

Adding caching, message brokers, or replicas to a diagram does not automatically deliver high performance or high availability. Every structural choice must be grounded in the actual scenario:

text
Requirement: During finals, rank queries must meet p95 < 300 ms.
Candidates: Real-time aggregation on every request; precomputed rankings; short TTL caching.
Costs: Freshness degradation, write amplification, complexity of cache invalidation, additional operational components.
Validation: Conduct load testing under agreed concurrency and data volume, and monitor tail latency.

Architecture design is about allocating responsibilities and risks under constraints, not about selecting patterns from a catalog.

Use ADR to Preserve "Why" ​

Diagrams typically show the current structure but struggle to explain why one design choice was made over another. An Architecture Decision Record (ADR) captures one important decision. The following is a hypothetical example, not an accepted decision for this repository:

markdown
# ADR-0003: The first version adopted a modular monolith

Status: Accepted

## Context
Four people maintain the first release, with one deployment per week.
Registration and settlement need local transactions; no module currently needs independent scaling or releases.

## Options
1. Modular monolith
2. Independent microservices

## Decision
Use a modular monolith, with explicit module APIs separating registration, scheduling, and settlement.

## Rationale
Independent services add cross-process failures and multiple deployment pipelines.
Current requirements do not yet justify those costs.

## Consequences
- Local transactions and deployment processes are simpler;
- Modules cannot be scaled independently;
- If the growth assumption fails, reevaluate the boundaries based on monitoring data.

An ADR should capture the context, alternative options, the final decision, the rationale behind it, and its consequences. When a replacement is accepted, create a new Accepted record, mark the old record Superseded, and link them. Preserve the old context and reasoning instead of rewriting history with today's explanation.

Only document decisions that significantly impact the system's structure, critical quality attributes, or reversibility. Decisions like "use four spaces for indentation" are better suited to coding style guidelines.

Keep Documentation Usable ​

  • Label diagrams with title, scope, audience, update date, and legend.
  • Ensure names in documentation match those used in code, deployment, and monitoring.
  • Review documentation and code through the same process; update both simultaneously when the code structure changes.
  • Remove outdated diagrams or clearly mark them as historical snapshots.
  • Walk through diagrams using key scenarios: normal flow, timeout, retry, partial failure, and recovery.
  • For decisions with low confidence, document validation methods and conditions that trigger a review.

Chapter Delivery Exercise ​

Complete the following for a system you are already familiar with:

  1. A System Context diagram;
  2. A Container diagram;
  3. A sequence diagram or state machine diagram that includes failure paths;
  4. Two measurable quality attribute scenarios;
  5. An ADR (Architecture Decision Record) documenting real trade-offs.

If any box, arrow, or component cannot be linked to a requirement, quality attribute, or constraint, ask whether it truly belongs in the architecture.

References ​

Built with VitePress | Software Systems Atlas