Tech Tuesday – Documenting Software Architecture The C4 Way
31 January 2017 |
Tiago Gonçalves | About a 8 minute read
Architecture diagrams are one of the most important forms of software documentation. They’re meant to explain and clarify the different parts of a system, but they often raise more questions than they answer.
Having been part of big projects in a variety of contexts, from banks to insurance companies, publishers to government bodies, one of the biggest challenges that I’ve faced in all of them was to have the developers speaking the same language and actually implementing what the teams of software architects had designed. Many times I’ve seen sprints worth of Agile teams’ work going down the drain just because the architects’ ideas were not clearly understood by the developers.
Discussion between the two tends to result in sets of drawn diagrams on whiteboards that everyone seemed to understand at the time, but when looking back to them a week later, just seem as incomprehensible as before the discussion. Proper documentation is therefore key to help solving this issue.
As a developer, one of the first things I try to get hold of when joining a new project, is the architecture, both the as-is (if existing) and the to-be. And often I’m given a bunch of diagrams that are made of boxes and lines which without someone to explain them, end up being useless or really difficult to understand.
So, what’s the point of drawing diagrams if I need someone alongside them to actually understand what’s going on there?
UML should be the standardised way to solve this problem, but the truth is that no one really seems to use it or even know it. Most of the teams prefer simpler and informal “boxes and lines” diagrams to represent their designs even though these usually require someone alongside to interpret them.
I recently attended a talk by Simon Brown where he focused on this communication problem and presented what can be a possible and simple way to help solving it.
Lack of common vocabulary
If you ask different people, developers and architects, to draw the architecture for the same system, you’ll end up with as many different diagrams. One of the reasons for this as explained by Simon, is that there’s a lack of a common vocabulary to think, describe and communicate about software architecture.
The variety of results from a simple Google search for software architecture diagram pretty much sums up the problem.
If you look at a map of London, whether it is on Google maps or just some random touristic map, you’re always able to read it and interpret it. This is because there’s a common set of concepts for which you can then create notations to represent.
A map will have forests, rivers, roads, towns, and even though these might have a different notation from map to map, they’re the common set of concepts (same abstractions) that allow us to correctly interpret different maps. Even if they have different notations from map to map, there’s always a key or legend in one of the corners that will map the concept with the notation.
So Simon’s goal is:
“…to see teams able to discuss their software systems with a common set of abstractions rather than struggling to understand what the various notational elements are trying to show. For me, a common set of abstractions is more important than a common notation.”
In software development we deal with so many concepts and at so many different levels of abstraction that it becomes really difficult to achieve this common vocabulary.
Static Architecture vocabulary
The primary aspects that Simon’s interested in solving are the different levels of abstraction of a system’s static structure. Once the static structure is understood, then it becomes easier to add other information such as runtime/behavioural characteristics, infrastructure, deployment models and so on.
So, the static infrastructure of a software system can be represented as a hierarchy of simple building blocks, and Simon has a vocabulary that we can use to describe them:
“A software system is made up of one or more containers (web applications, mobile apps, standalone applications, databases, file systems, etc), each of which contains one or more components, which in turn are implemented by one or more classes.”
These 4 words are tied to different levels of abstraction, and all of these together should be enough to properly describe the static structure of a software architecture.
Software System: highest level of abstraction that represents something that delivers value to its users (human or not).
Container: context or boundary inside which some code is executed or some data is stored. They’re separately deployable (e.g. database, server-side web application, mobile app).
Component: a grouping of related functionality encapsulated behind a well-defined interface. A component is implemented by one or more classes (e.g. login component, search component).
Class: a Java class, or a class in whatever language you use.
By finally having a common vocabulary in place that we can use to describe software architecture, it becomes easier to find a common way of drawing diagrams for the different levels of abstractions. Simon came up with his own collection of diagrams that we can use to describe the static structure of a software system, he calls it “The C4 Model”.
The C4 Model
The C4 Model is Simon’s attempt to create a common way of describing the static structure of software architecture, this means the software systems, containers, components and classes.
C4 consists of a set of 4 diagrams that provide views to the different abstractions of a software system:
These diagrams should be self explanatory and to help that, annotations and meaningful text should be added. Below is an example provided by Simon about an application he created (Techtribes.je) and that he describes as “the only way to keep up to date with the IT, tech and digital sector in Jersey and Guernsey, Channel Islands”.
Shows the techtribes interactions with users and other external systems.
Shows the different containers that are separately deployable.
By zooming in to one of the containers we get its component view. The following diagram shows the different components within the Content Updater container.
Classes / Code
Finally, the 4th and last layer can be represented by an UML class diagram for the component. In this example we have the class diagram for the Tweet Component.
As this layer can be obtained from the code itself, it’s often not required. Even Simon says “…I don’t typically draw class diagrams for anything but the most complex of components or as a template when I want to describe a pattern that is used across a codebase”.
As you can see, it becomes pretty easy to understand what Techtribes.je is about, and you didn’t even had to bother Simon for clarity.
Each view of the system is clean and only shows what’s really relevant for a developer to understand the architects idea. Actually, it even looks simple enough for non-technical people to understand it!
From these diagrams you can then get into further documentation about the specifics of the system, such as data models, process flows, infrastructure model and so on. And for most of these, UML is usually a good fit.
With such way of describing architecture, I can easily start on a project and understand what’s being built, helping reduce the gap between architects and developers. Of course, this is just the first step to understanding a system, but it’s probably the most important thing you can get when you land on a new project. And imagine finding all this without having to bother architects or other developers!
I’m spreading Simon’s idea here at AND Digital and at our clients, if you do the same, maybe one day we’ll all finally be able to think, describe and communicate effectively about software architecture!Read More From This Author
React Native Engineer (London)
Champion software quality and technical vision for AND and our clients, work on large-scale projects and help junior and mid developers grow in their roles.
Technologies you will be using
Tech Lead (Reading)
Bring your expert tech knowledge to the table to influence the direction of projects, whilst coaching and your team through engineering best practices.I'm Interested
DevOps Lead (Reading)
Bring your delivery expertise to the table, leading the pack as ambassador on operational requirements, influencing and continuous development.I'm Interested