Software Architecture / Foundations: promises, structure, and ownership / Lesson 3
Use architecture views to answer different questions
Keep context, containers, components, runtime interactions, and deployment responsibilities consistent.
On this page
Lesson goals
- Choose a view for its audience and question rather than drawing every possible level.
- Trace a failure story through relationships and deployment boundaries.
Start with people and external systems
A context view explains why the workshop system exists and how people and external systems interact with it. It should be readable without knowing the implementation language. Label relationships with a purpose, such as reserves a seat or sends a confirmation, rather than leaving arrows unexplained. Include the system boundary and distinguish systems operated by other owners. A context diagram is not a network map: adding every router makes the business relationship harder to see and belongs in a different view when relevant.
Explain executable applications and data stores
In C4 terminology, a container is an application or data store, not necessarily a Docker container. A browser application, server application, and reservation database can therefore be separate containers. Show responsibilities, technology where it clarifies communication, and relationship direction. Specify whether a connection is synchronous HTTP, asynchronous messaging, or database access. Deployment instances are a separate issue: three replicas of the same server application do not automatically create three different logical responsibilities or three independent services.
Learner -> Browser UI: request reservation
Browser UI -> Booking API: HTTPS reservation request
Booking API -> Reservation Store: atomic seat allocation
Booking API -> Mail Provider: notification request
Each line records direction and purpose. The last relationship still needs a runtime decision about synchronization; the inventory alone cannot promise atomicity across the mail provider and the store.
Zoom only where it explains a decision
A component view might show the reservation use case, seat-allocation policy, persistence adapter, and notification adapter inside the server. Explain which interface crosses each boundary and why it exists. Avoid decomposing every class into a diagram that duplicates source code and becomes stale immediately. A useful component diagram highlights an important dependency rule, such as domain policy depending on an abstract reservation repository rather than a vendor database client. Link the diagram to implementation locations or checks that help maintain that rule.
Tell a scenario with success and failure branches
Static boxes do not reveal order, waiting, or partial failure. Add a runtime story for the last-seat race or a mail timeout. Name which participant confirms the durable reservation and when the user receives a result. The example deliberately separates a committed reservation from notification delivery. A timeout after commit leaves an uncertain client outcome; a retry needs a stable request identity rather than a second unqualified reservation. These observations can uncover requirements that a neat static diagram conceals.
1. Client sends reservation with request_id R17.
2. API records reservation and request outcome atomically.
3. Connection fails before the response arrives.
4. Client repeats R17.
5. API returns the previously recorded outcome.
This is a proposed protocol, not an executed integration test. Its guarantee depends on atomic storage and request identity rules that later design work must specify.
Show where faults and trust boundaries exist
A deployment view maps software to execution environments and communication paths. It can explain which replicas share a database, which network boundary protects a store, and which dependency remains external. Do not imply high availability merely by drawing duplicate boxes: shared storage, a shared host, or one configuration source may still be common failure points. Record diagram date, legend, ownership, and intended environment. Review all views together after a change so a new worker appears consistently in responsibilities, runtime interactions, and deployment assumptions.
Common errors and fixes
Container is interpreted as a required Docker deployment.
- Why it happens
- A diagram abstraction was confused with a packaging technology.
- How to fix it
- Define the C4 term and label the actual execution environment separately.
- Prevent it next time
- Include a legend for overloaded terms.
Arrows have no direction or purpose.
- Why it happens
- The diagram was treated as decoration rather than a communication model.
- How to fix it
- Name the initiator, protocol, and reason for important relationships.
- Prevent it next time
- Ask a new reader to narrate a workflow from the view.
Two replicas are claimed to remove all single failures.
- Why it happens
- Shared dependencies were absent from the deployment view.
- How to fix it
- Map host, storage, identity, and configuration dependencies explicitly.
- Prevent it next time
- Review a concrete dependency failure alongside every redundancy claim.
Check your understanding
1. Which view explains why a learner receives no response after a reservation commits?
Show worked solution
Use a runtime interaction view showing the client, API, transaction commit, and broken response path. The static container view establishes participants but cannot show the ordering that creates uncertainty. Add the retry and outcome lookup behavior, then check deployment details only if a particular network or process failure is relevant.
2. A component diagram contains every helper method. How would you revise it?
Show worked solution
Identify the architectural question first, such as enforcing domain independence from persistence. Keep the components and interfaces that explain this rule, link to code for detailed implementation, and remove details with no decision value. Assign an owner and review trigger. More boxes do not produce more architectural understanding when they obscure the dependency that matters.
Key takeaways
- Different views answer different questions about one system.
- A runtime story exposes uncertainty and ordering that static structure cannot.