The C4 Model - A convenient and efficient way to visualise Software Architecture
Documenting Software Architecture diagrams is a fundamental step in the design of software. The process you follow to create such documentation should exhibit the following characteristics at a minimum.
Convenient - Personally, I always felt the equivalent of a writer's block when it comes to creating software architecture diagrams. I used to spend lot of time trying to visualise the diagram without actually putting it on paper. It's important to note that the process of documentation itself should not end up becoming another project in our head. It should be easy for someone to understand get started quickly without spending too much time thinking about the visual design of the diagram itself.
Efficient - Ease of use should not trump efficiency. An easy process of creating software architecture diagrams should not in turn derogate the meaning of what the architecture is trying to convey. The diagrams should be self sufficient when it comes to the completeness of capturing software architecture.
The C4 Model proposed by Simon Brown addresses these two factors to a large extent. The model builds upon traditional UML based diagramming process but simplifies it.
The C4 Model
C4 model is made up of 4 levels of architecture diagrams with increasing detail by level. It builds on the concept of abstraction where the fundamental idea is to keep abstracting away the complexity to a lower level (or higher depending on how you put it).
Let's take a look at the 4 levels.
The C4 diagrams should begin with one diagram which outlines the ecosystem of applications your software system is going to fit into and the users it is going to serve. At this level, the connecting arrows between different entities should highlight usage and integrations.
The next level of detail is the container diagram. There should be one container diagram per software system added to the context diagram.
Container diagram should show independent pieces of software/applications which offer a certain functionality and which can be deployed and maintained independently. In a micro-services world, a container can be a docker container that is running in production, or a database.
Each container will be made up of different components. Components are modules within a container. As above, there should be one component diagram per each container you have in your container diagram. For example, in case of a Spring Boot application, components are essentially the controllers, services and DAO layers that you write within your application.
Code diagrams are optional. Code diagrams are meant to explain your components with the help of UML. In most cases, software architecture diagrams don't need to go this deep.
Let's take an example of a food delivery app built for multiple platforms supported by a bunch of micro-services in the backend.
A sample architecture diagram for such system would look something like below. We will only look at Context, Container and Component diagrams for simplicity's sake.
The first level diagram is context.
The above program just outlines the users who would be using the app and possible integration touch points in the software eco system to which the application is being deployed.
Going a level into the Software System, we will have the containers outlined as below
We have three different client apps (iOS, Android and Web) shown as three containers. Similarly, the backend components are shown as separate containers by themselves.
Let's pick only the FDA Backend container and outline the components inside it. In a simple manner, the components and their relationships can be outlined this way. There should be one component per each container. We are only looking at one as an example.
Disclaimer: The architecture shown above is far from the best there can be. We are not talking about good architecture here, we are talking about good ways of presenting architecture. 😀
Points to note
- The direction of the arrows doesn't matter as long as the text associated with the arrow makes sense with respect to the direction of the arrow.
- In every level, retain the connecting component from the previous level to still maintain the context of the connecting arrows.
Did you find this article valuable?
Support Pavan Andhukuri by becoming a sponsor. Any amount is appreciated!