The purpose of a system influences the architecture, but system architects are often involved after the business need is identified. The business case is often lost in technical documentation, because those points are lost in slides prepared by the business. Maintaining a complete story in technical documentation betters odds of projects aligning to purpose. Let’s consider how to describe and model a system before recording architecture decisions.
Architecture Decision Records (ADR)
- are a best practice for documenting why an architecture is chosen.
- are evidence of due diligence in the selection process.
- are important for future maintainers of a system.
More context available in Recognizing ADR Value
We’ll contextualize systems using an approach insprired by the C4 Model. Our key takeaway from C4 is thinking about the system at multiple levels. This method decreases the information to communicate in a single diagram. Another technique we’ll borrow from C4 is modeling instead of diagramming. We’ll use textual templates and annotations to achieve our model. This representation will keep our model approachable to business stakeholders.
First, let’s consider where system documentation should live. Preserving information involves ensuring records can endure time and change. Therefore, the most necessary features are change management and vendor neutrality. Visual editors and tooling that archive information inside vendor products are a recipe for data loss. Without naming specific products, let’s just say many popular commercial wikis are a mistake. Consider yourself lucky if you haven’t lost documentation in upgrades or vendor migrations. At the least, you’ve likely experienced formatting issues you learned to tolerate. Preventing documentation loss involves not giving away control for convenience.
Keep it simple. Text files are a vendor neutral medium to capture information. They are also versionable in the same tools software is built. In addition, modern source control tooling is built for collaboration on open standards. All that said, let’s proceed with a dedicated git repository for documentation. We’ll format with markdown and lean towards managing docs as code.
C4 Model has, you guessed it, four levels:
We can model these in well known templates from the agile methodology:
User stories are, not suprisingly, focused on user needs.
The common template follows a "As a _, I want _, so I can _."
format.
This structure provides a big picture view of the problem space.
Context is the first C of the C4 model, and our context is customer focused.
Let’s try modeling with user stories.
As a $UserLabel,
I want to $ActionLabel $ContainerLabel,
so I can $ContainerValue.
The $
placeholders above can be completed as:
As a `contributor`, I want to _maintain_ the Lexical.cloud catalog,
so I can `spread awareness of options for cloud architecture`.
Resulting in a visualization of:
flowchart TD
%% entities
U1["Contributors"]
%% groups
subgraph G1["Users"]
U1
end
subgraph G2["Lexical.cloud
- Spread awareness of options for cloud architecture
"]
end
%% relationships
U1 -->|maintain| G2
%% styles
classDef cluster fill:white,stroke:grey,stroke-dasharray:5
The "Given _, when _, then _."
structure of behavior-driven dev (BDD) can further this representation.
Containers and Components, the next Cs from C4, will dive further into the previously defined context.
Containers are groups of components and other containers. The nesting can go multiple levels deep.
Beyond components is only code, the final C of C4, represented in traditional software methods.
Given $ContainerLabel $ComponentLabel,
when $ComponentLabel $ActionLabel $ComponentLabel
or $ComponentLabel $ActionLabel $ContainerLabel,
then $ContainerLabel $ActionLabel $ComponentLabel.
The $
placeholders above can be completed as:
Given `Lexical.cloud` is a `community data` project,
when `contributors` _maintain_ the `community data`,
then `community data` _populates_ the `frontend` and `backend`.
Resulting in a visualization of:
flowchart TD
%% entities
U2["Contributors"]
%% groups
subgraph G1["Users"]
U2
end
subgraph G2["Lexical.cloud"]
G3
G4
G5
end
subgraph G3["Community Data"]
end
subgraph G4["Frontend"]
end
subgraph G5["Backend"]
end
%% relationships
U2 -->|maintain| G3
G3 -->|populates| G4
G3 -->|populates| G5
%% styles
classDef cluster fill:white,stroke:grey,stroke-dasharray:5
Let’s consider the benefits of documenting a system backstory as code:
In short, documenting context clarifies past and present state for future decision makers. ADRs do the same for decisions made in a given context. Combining these methods better explains why a decision was reached. See this in action on Lexical.cloud’s project docs.
Let’s continue exploring ADRS with this series of articles: