The Art of Crafting Architectural Diagrams. Guidelines
The Art of Crafting Architectural Diagrams. Guidelines
Guidelines to follow when creating architectural diagrams
Apart the above pitfalls, which must be part of a prerequisite checklist in order to avoid them, there are also general guidelines on how to properly create diagrams:
Choose the optimal number of diagrams
- As Philippe Kruchten said, "architecture is a complex beast. Using a single blueprint to represent architecture results in an unintelligible semantic mess." To document modern systems we cannot end up with only one sort of diagram, but when creating architectural diagrams it is not always straightforward what diagrams to choose and how many of them to create. There are multiple factors to take into consideration before making a decision; for example, the nature and the complexity of the architecture, the skills and experience of the software architect, time available, amount of work needed to maintain them, and what makes sense or is useful for meeting stakeholders concerns. For example, a network engineer will probably want to see an explicit network model including hosts, communication ports and protocols; a database administrator is concerned about how the system manipulates, manages and distributes the data, etc. Based on all of these aspects, it is recommended to pick up the optimal number of diagrams, whatever that number is.
- If there are insufficient diagrams (e.g. under-documenting), parts of the architecture might be hidden or undocumented; on the other hand, if there are too many (e.g. over-documenting), the effort needed to keep them consistent, updated and not fragmented might considerably increase.
Keep structural and semantical consistency across diagrams
- Every diagram should be consistent with the others in terms of boxes, shapes, borders, lines, colors, etc. The structural look and feel should be the same and every stakeholder should have no difficulties in understanding diagrams created by different developers inside a team. Ideally, stick to a common diagramming tool and reuse it across all projects.
- From the semantical point of view, all of these diagrams should be periodically synchronized to latest code changes and between them, since a change in one diagram might impact others. This process might be manually or automatically triggered by using a modeling tool. The latter is the preferred mechanism but this depends from project to project, in all cases the idea is to maintain consistency between diagrams and code, independent of the method or tool. Simon Brown said "diagrams are not useful for architectural improvement if they are not connected to the code", which emphasizes the idea of semantical consistency.
Prevent diagrams fragmentation
- Having multiple diagrams might make the architectural description difficult to understand but also a significant effort in maintaining them. As a side effect, fragmentation might appear (e.g. for example two or more diagrams illustrate the same quality attribute - performance, scalability, etc. - but each of them is individually incomplete). In such cases it is recommended to either remove the diagrams which do not reflect relevant quality attributes (linked to architecturally significant requirements) or, even better, to merge diagrams (e.g. concurrency and deployment).
Keep traceability across diagrams
- To be able to check the history, making comparisons between different diagram versions plus easily reverting to a previous version is also important. Using a modeling tool which does not allow that might be an impediment. The latest trends in the industry rely on using a simple and intuitive plain text language to generate the diagrams out of it, which seems to solve the traceability concern. Another advantage of such an approach is that it implicitly ensures a homogeneous structural consistency between diagrams.
Add legends next to architectural diagrams
- If you do not follow a standard architectural description language (e.g. UML, ArchiMate), detail every piece of the diagram in the legend (e.g. boxes, shapes, borders, lines, colors, acronyms, etc).
- If this is not the case, in the legend just add the architectural description language as a key and there is no need for additional explanations, since every reader will follow on that language specifics to understand the diagram.
Does the Architectural Description Language (e.g. UML, ArchiMate, etc.) make a difference?
There are a lot of opinions regarding which is the right description language to be adopted in the project. Some people might argue that UML is rigid and not flexible enough to model the architectural design, a point of view which I agree with. Nevertheless, in some cases it might be more than sufficient for documenting the fundamentals of an architecture without relying on any UML extensibility features like profiles and stereotypes. By taking a look at other description languages, we can see that ArchiMate is more powerful and suitable for modeling enterprise systems in comparison to UML; there is also BPMN which is particularly targeted to business processes, etc. The comparisons might continue, but I do not intent to make any deep review across them, since this is not the goal of this article.
Having an architectural description language comprehensive and flexible enough is a big step forward and this should be a solid criteria when choosing it. But from my perspective, the real cause resides somewhere else and is related to the fact that architectural documentation is not created at all. People often find creating it boring, useless or pointless. The number of software projects without, or with improper documentation, is huge. I do not think people are intensively creating or involved in the creation of architectural diagrams using an improper description language, and if they were to replace them with a better one the results would be very different. No, people are not creating any architectural documentation (including architectural diagrams), and even worse, most of them have no idea about how to properly create it. These are the things we need to address first- to understand why documentation matters and how to properly create it (by training software engineers); then the selection of proper tools comes naturally.
How can diagrams be kept up-to-date as the system is developed, and changes to the architecture materialize
There are few approaches to keeping diagrams updated; below I will express three of them. The first option, and the easiest one, would be to automatically generate diagrams out of the source code, which is the ground truth. This guarantees they are all consistent to the code. Unfortunately, with existing tools this is not yet fully possible (at least to my knowledge), since actual tools cannot create any type of accurate and meaningful diagram only based on the source code, without significant manual intervention. Len Bass said "the ideal development environment is one for which the documentation is available for essentially free with the push of a button", implicitly auto generating the diagrams, but we have not reached that point.
The second approach would be to first design the diagrams using a dedicated tool which then generate the source code skeletons (e.g. components/packages with boundaries, APIs) used later on by developers to fill in the code. This way, every change in the architecture needs to be triggered from the diagram itself which automatically might regenerate or update the code skeleton.
The last case involves manually updating the diagrams every time a new feature - which has an impact on the architectural design - is implemented. To be sure all code changes are reflected in the diagrams, it is recommended that updating diagrams to be part of the definition of done in the development process. This scenario is less recommended because it could easily cause outdated or inconsistent diagrams (e.g. developers often forget or are not in the mood to update diagrams) and unfortunately this still happens in a majority of the projects.
Taking into account existing tools, my recommendation is to have a mix; to blend automatically and manually create diagrams. For example, try to auto generate diagrams, which can be reasonably rendered by tools based on source code without too much noise (e.g. too cluttered or meaningless information). In this category we can include either diagrams with a high degree of volatility (e.g. more prone to frequent development changes, usually having a lower abstraction) or, on the contrary, static diagrams. Some such diagrams might refer to context diagrams, reference architecture diagrams, package diagrams, class diagrams, entity diagrams, etc. Nevertheless, in some cases, it is not obvious based only on the source code how the system meets some quality attributes (e.g. availability, scalability, performance), hence the automatic creation of diagrams is not a sufficient option. It needs to be complemented by manually modeled diagrams. Some examples of such diagrams include sequence diagrams, state diagrams, concurrency diagrams, deployment diagrams, operational diagrams, etc.
What complications (or simplifications) emerge for architectural diagrams when dealing with modern architectures (e.g. microservices)?
Microservices or any other modern architectural style (e.g. serverless, event driven) only drives the structure of the system, how the components communicates each other (e.g. relationships between them) and what principles govern them. Personally, I don't think the architectural style should change the rationale or concepts around creating the diagrams (and implicitly the architectural description), neither what they should capture. Nevertheless, when we talk about modern systems architectures, usually having higher levels of complexities in comparison to old and classical systems (e.g. monolith), they definitely have an impact on the architectural description and implicitly on the diagrams, in the sense that there are multiple considerations to take care of. Such considerations might be in regards to understanding the number of distributed components (e.g. distributed micro-services), the type of each component, how components communicate to each other (e.g. boundaries, APIs, messages), their lifecycle and who owns each component.
Taking all of these into account, views capturing system decomposition, development, deployment and operability should be considered by default. Imagine a system with an impressive number of micro-services, for example; in such a case the number of diagrams might significantly increase because each microservice might end up in having its own set of diagrams. Issues regarding consistency (e.g. changing the API of one service impacts other X services, therefore all impacted diagrams needs to be updated), fragmentation (e.g. highly availability or performance between distributed services is not consolidated in one diagram) or cross-cutting concerns (e.g. who is in charge to illustrate, in a consolidated manner, aspects like monitoring or security across entire system elements) might not be easily handled. On top of this there might be challenges related to teams’ coexistence and collaboration during project development, and even afterwards, in order to maintain it.
To summarize, moderns systems with complex architectures might bring additional concerns which could lead to complications even at the diagrams level.
Interested in improving your Software Architecture skills?
Check out our Software Architecture Methodology and Concept training.Ionut Balosin