Simon Brown has written a straight to the point, no hassle, book about software architecture for developers. Are you scared of UML and power point architects, then this book is for you.
Simon Brown is an Author from England. He has consulted for many years in software architecture. What is it, and how can you document it? How can a programmer take the step to becoming an architect. How do you define the term architecture? He regularly speaks at conferences.
Definition of Architecture
Before we can talk about software architecture, how to document it and the different levels of abstractions, we should define it. The definition that Simon Brown use in the book is twofold.
Software architecture is about structure and vision
Software architecture is used both as a noun and as a verb. As a noun software architecture is about structure. How to divide the software into modules and enhance code constraints so the system can grow without the developers loosing control. As a verb it is about having a vision about the finished product and communicating this to developers and the stakeholders.
Simon Brown makes an important distinction between design and architecture.
All architecture is design but not all design is architecture.
He goes on to clarify and specify that architecture represent the significant design decisions that shape a system, where significance is measured by cost of change. The problem is to recognize when you are making a design decision and when you are making an architecture one. This is an intuition that is built up over years of experience. Although some of the cases it is pretty obvious. The decision to go for an object-oriented database vs a relational one is obviously an architecture decisions. You can make layers of abstractions and try to make it as easy as possible to swap out the persistence layer but either way, changing it will cause the team a lot of pain.
Both uses of the term architecture, as defined above, need to have some way of visualizing it. The first taught that I guess most people get is UML. The Unified Modelling Language. An agreed upon notation for visualizing software. It is perfect.
Problem with UML
Uml is a wonderful language. The only problem is that there are very few developers who can UML. And those that do know it make diagrams for the ones that don’t. Lets take an example. Can you distinguish between these arrows without referring to the labels in this legend?
So if UML is not the answer, how about making a up a notation?
Problem with homemade diagrams
Also, when you quickly want to describe something or get a design across, the last thing that should be in your way is the notations. That is why Simon Brown has seen over and over developments teams making up their own notation. However that notation is not documented anywhere. The corollary is also a notation that is not very precise.
The diagrams also mix up different levels of abstractions. One part of the diagram can talk about the deployment of modules on a specific machine. Another about technology desisions. Yet another is the interactions between an actor and the CRM system.
The problem with most definitions of architecture is that they put all their emphasis on architecture as a noun. The most typical diagram that you see, and that validates this, is an overview of the different technologies. One such example is this:
If you present this diagram to a new member of a team, what would you learn about the system?
The goal is to look at the architecture at different levels of abstractions. And with each level know where you are.
C4 – Context, containers, components and classes
Simon Brown has created a set of diagrams called C4. It stands for Context, containers, components and classes. 4 different levels of abstractions. Going from system with external dependencies to classes which show the internal structure. The lower levels are more tedious to create and are more directed against the developers at the team. The to first are more for the customers as well.
This is the highest level of abstraction. It shows the something that delivers value to somebody. This diagram shows sets the scene including key system dependencies and actors. The picture shows an example application that Simon Brown uses throughout the book. Notice that we are not only showing the external
actors and systems but also a small description about their involvement with the software we are building.
This diagram should only take a couple of minutes to create. There is really no excuse to not have it. We are using Confluence with the gliffy plugin on our current project. It makes it possible for everyone to alter the diagram and keep a log of all the changes to it. It is possible to comment on the page where the diagram is.
The point is that all the diagrams in the C4 modell should not be the product of a high level architect. A person that with a stroke of genius made the correct diagrams in solitude. There is no such person. Instead all the team members should have an active relationship to it. Every time we make a change to it we print it out on A3 paper and hang it up on the wall. More often than not we are standing next to them and discussing. The diagrams lose their relevance if they are not connected to the code or reality.
The container diagram is one step lower in terms of layer of abstraction compared to the context diagram. Let us look at an example for the same use case as above. The diagram shows the high level technology choices, how responsibilities are distributed across them and how the containers communicate. This, and the context diagram, are the diagrams that are most used on my current project.
One rule of thumb that helps me find containers from components is: if you can deploy the element on a separate machine, then it is a container. Such as a .dll is typically not a container in that it can not be deployed by itself on a separate machine but is a part of a container. Simon Brown defines “containers” to mean logical executable or processes that make up your software system. Examples are: Web servers, application servers, enterprise service buses, databases, web browser, cron jobs.
The intent of the diagram is to help the following answers: what is the overall shape of the software system? What are the high-level technology decisions? How are responsibilities distributed across the system? How do containers communicate with one another? As a developer, where do I need to write code in order to implement features?
The last question is an interesting one. Pretend you are a new developer at a software project. You open up the ticket system and pick up a task. Where should you start? What are the questions that I should be asking? What are the other parts that my coworkers are working on? The container diagram can aid in that regard. It also brings forward a collective mental model of the software that helps to increase collaboration and understanding.
As we can see on the diagram the containers should be specified with name, technology and responsibilities. Also the interaction between them has annotations denoting: the purpose of the interaction, communication method, communication style(synchronous, asynchronous, two phase commit etc) and protocols and port numbers. These annotations make the diagram stand out from the ordinary type of architecture diagrams. It is often understood that the information that the annotations specify are implementation details. The assumption take root in the separation between architect and developer. A separation that these diagrams try to remove. To use a sql or no-sql database is NOT an implementation detail. Same goes for communication methods, technology choices, protocols etc.
Now that we have a relative high level overview of the system we can choose to drill down further into components. This is not mandatory and it is perfectly fine to only show diagrams for certain components. The component diagram should help you answer the following questions:
- What components/services is the system made up of.
- It is clear how the system works at a high-level?
- Do all components/services have a home(i.e. reside in a container)?
It is important to emphasis that we only want to make diagrams for one container of a time. You can use a wiki with links so you can click and navigate into the various containers to see their respective component diagrams for example.
The components are the coarse-grained building blocks of the software you are creating. You should specify the following for each component: name, technology, responsibilities. This diagram should also have, like the other diagrams, annotated the interaction between components.
The audience for this diagram are technical people within the software development team.
Class diagrams are the smallest building blocks of our software system. Simon mentions that it is not always necessary to have class diagrams. He further says that he will draw a small number of high level UML class diagrams if he want to explain how a particular pattern or component is implemented. The diagrams does not need to be detailed. They can be high level class diagrams.
Simon Brown also has a whole chapter about documentation. It is often tempting to think that the code is self documented and that the tests in TDD will document the requirements. It is not the case. Simon gives us a blueprint for creating a software guidebook which works like a guide for the software. It consists of elements like: functional overview, quality attributes, constraints, external interfaces, decision log etc. It is important to distinguish between documentation for internal use by the developers and documentation that is delivered with each release. The software guidebook is the latter.
Just to give an example, let us pick quality attributes. They document the quality attributes/non-functional attributes using goals that are specific measurable, achievable, relevant and timely. On such example is max down time. Another is how responsive the application should be to various interactions. These are attributes that are most likely forgotten and pushed asides in favour of functional requirements. The quality requirement do however come back in the end of the project, but not in a positive way.
Simon Brown has written an excellent book. He gives a pragmattic approach to software architecture and looks at various elements of it. From documentation, sketching architecture, the architecture role etc. You can buy the book at leanpub.