Software architecture diagrams are a great way to explain and document how a software system works. Static diagrams, whether drawn on a whiteboard or with a general purpose diagramming tool such as Microsoft Visio, tend to get out of date quickly and often don't reflect the structure of the code. On the other hand, automatically generated diagrams, such as UML class diagrams created by reverse-engineering the code, typically show far too much detail, limiting their usefulness.
Drawing software architecture diagrams
If you've ever been asked to create a set of software architecture diagrams to describe a software system, you'll know that there are a number of approaches you can take.
1. Sketches on a whiteboard
Sketching out software architecture diagrams on a whiteboard is probably the starting point for many of us. Although it's quick to get started, the resulting diagrams are often erased because somebody else needs to use the whiteboard. Taking a photo of the whiteboard allows you to at least capture the sketches, but that resulting photo isn't something you can update easily.
2. Drawing tools
A logical next step for many people is to copy the whiteboard diagrams by recreating them in a general purpose drawing tool such as Microsoft Visio, OmniGraffle, Lucidchart, Gliffy, etc. Such tools make sharing and updating the diagrams easier, but the diagrams still need to be updated manually if they are not to become out of date.
3. Modelling tools
Modelling tools such as Rational Software Architect and Sparx Enterprise Architect build on the capabilities of drawing tools by allowing you to create a model that you can then visualise in a number of different ways, sometimes with different notations (e.g. UML, SysML, ArchiMate, etc). In theory, this provides a much richer set of diagrams because it allows you to ensure consistent naming of elements between diagrams as well as introducing a set of rules to describe elements and their relationships. The downside of modelling tools is that it takes some effort to create the model and keep it up to date, plus such tools can sometimes seem overly restrictive or heavyweight.
4. Reverse engineering
Another way to create software architecture diagrams is to generate them automatically from the code. Many modelling tools, static analysis tools and development environments include this capability, generating UML package and class diagrams to describe your software. This approach does provide a way to keep diagrams up to date easily but the resulting diagrams tend to show far too much detail because they are showing classes rather than components. In essence, many of the diagrams you'll see created by reverse engineering the code are not "software architecture" diagrams. They simply show a visual representation of the code structure.
5. Architecture description languages
An architecture description language is a more formalised approach to creating a software architecture model. Some, like Darwin for example, offer a text-based language that you can use to describe the architecture of a software system. Diagrams are then created using supporting or additional tooling such as Graphviz. Using a text-based language is certainly appealing for us as software developers, but architecture description languages have never really seen mainstream adoption.
Why not UML?
Tooling aside for the moment, there's still the question of notation, and specifically UML. UML provides a standard set of abstractions with which to think about and describe a software system, along with a standard set of boxes and lines (the notation) to represent those abstractions. Anecdotal evidence suggests that UML usage is on the decline, with notational complexity and a lack of UML knowledge commonly being cited by teams that no longer use it. The other problem with UML is that it doesn't really support a good way to draw high-level software architecture diagrams. UML does, however, provide a great way to describe component implementation details using class, sequence/collaboration/communication and state diagrams.
An alternative approach
The C4 model
Based upon his experience of working with thousands of software developers around the world, Simon Brown has created the C4 model, which is a simple set of diagrams that can be used to communicate the static structure of a software system, based upon a simple hierarchical set of abstractions that can be used to think about and describe the static structure of a software system.
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.
Visualising this hierarchy is then done by creating a collection of System Context, Container, Component and (optionally) Class diagrams.
Structurizr and "software architecture as code"
Structurizr is an implementation of the System Context, Container and Component diagrams, supplemented with a dynamic diagram that takes its influence from the UML collaboration/communication diagram. In essence, the goal of Structurizr is to allow software developers to easily create software architecture diagrams that make sense, reflect the code and remain up to date when the code changes.
The concept is that, using the Structurizr client libraries, you create a software architecture model using code, either by manually creating model elements or using static analysis and reflection to extract elements (e.g. components) directly from the codebase that you want to model. The resulting software architecture model is exported as a JSON document and uploaded to the Structurizr API so that the model can be rendered and shared via the web. In essence, Structurizr is an implementation of an architecture description language, specifically focussed around the C4 model.
No more endless hours spent messing with drawing tools, manually drawing boxes and lines. You create a software architecture model using code, Structurizr visualises it for you.
The software architecture model is created using code, so it can be easily versioned alongside your production code.
Static diagrams are hard to change and work with once they start to get large. Having the software architecture model as code puts you in control.
Integration with your build process means your software architecture model can be continuously kept up-to-date, especially if you extract parts of the model from your codebase.
Code provides opportunities
Compared to static diagrams and traditional modelling tools, representing a software architecture model as code opens a number of opportunities for creating the model and communicating it.
- Code is familiar: Code is familiar to us as software developers, so let's take advantage of this rather than creating another language with which to represent a software architecture model.
- Flexibility for creating models: In addition to manually writing code to create a software architecture model, we can also write code to extract architectural concepts (e.g. components) from our production codebase using techniques such as reflection, introspection and static analysis.
- Flexibility for visualising models: Writing code to create the views of a software architecture model provides you with the ability to slice and dice the model as needed. For example, showing all components for a large system will result in a very cluttered diagram. Instead, you can simply write some code to programmatically create a number of smaller, simpler diagrams; perhaps one per vertical slice, web controller, user story, etc. You can also opt to include or exclude any elements as necessary.
- Versionable: Since the models are code, they are also versionable alongside your codebase.
- Living documentation: The code to generate the model can be integrated with your automated build system to keep your models up to date; providing accurate, up-to-date, living software architecture diagrams that actually reflect the code.
If you're looking for more information, Simon Brown's Software architecture as code talk from the "Devoxx Belgium 2015" conference provides a good summary of what Structurizr is all about and the background behind why it was created.