The Art of Crafting Architectural Diagrams - Identifying Pitfalls
Based on my experience as a software architect and technical trainer, there are a lot of discrepancies between projects and inside the project team from developer to developer in the way architectural diagrams are created. I saw a lot of issues regarding inconsistency, fragmentation, and granularity of the rendered information and the look of the diagrams. In comparison to an architectural model which must be formal and standardized, the diagrams might not necessarily be formalized or follow a specific standard.
Nevertheless, diagrams must be self descriptive, consistent, accurate enough and connected to the code. That’s why it is important that every architect or software engineer rely on several guidelines when creating architectural diagrams, since they are the common ground of communicating the application’s architecture over time (e.g. structure, elements, relationships, properties, principles) and across different stakeholders having various technical backgrounds and concerns.
Current pitfalls when designing architectural diagrams
Before going deeper into possible issues, I would like to have an analogy to an English idiom which says "a picture is worth a thousand words". As per this wiki explanation, "it refers to the notion that a complex idea can be conveyed with just a single still image or that an image of a subject conveys its meaning or essence more effectively than a description does". The same concept applies for an architectural diagram: if it raises more questions than answers, the diagram is not well created. Do not let an architectural diagram require thousand of words or clarifications!
Example of an improper architectural diagram. It suffers most of the issues described below
Let’s now iterate through a list of pitfalls which might hinder the process of properly creating architectural diagrams.
What does a box or shape denote?
- Using any kind of box or shape which is not properly documented might cause multiple interpretations. It might be associated with either a piece of data, a bunch of code, or a process. Just a simple box in a diagram might raise multiple doubts and it is very important to avoid them by explicitly adding details about the box or shape meaning in the diagram legend.
- Each edge of a shape (e.g. dashed, dotted, etc) can be misunderstood in the case of a poor diagram. Does a specific border refer to a specific component type (e.g. a dashed line refers to a container, a microservice, a layer, etc.), or it is just the designer’s preference to have a rich look and feel? Avoid such confusion by providing accurate details in the legend diagram when choosing multiple or non-standard edges.
- A line or an arrow can be interpreted either as a data flow (e.g. data flows from system A to system B) or as a relationship across elements (e.g. component A depends on component B). In most cases the relationships or data flows represented by arrows do not converge in the same directions and it is important to explicitly write this in the diagram legend.
- Even if the line refers to a data flow or a relationship across components, the communication type (e.g. in case of data flow) or the association type (e.g. in case of relationship) denoted by that line or arrow must be detailed. For example, if the line represents a data flow, the communication might be synchronous or asynchronous, but if the line refers to a relationship, it might be represented by a dependency, inheritance, implementation, etc. All of these details must be present in the diagram legend.
- Having a ‘perrot’ policolor diagram (e.g. multiple colors for boxes, lines) without any proper documented intention might raise multiple questions (e.g. why are some boxes green and others red? Why are some lines black and others blue?). The color scheme is less important in a diagram, and using a rich number of colors does not bring too much additional content or valuable information. A diagram could also be self explanatory and well designed just by using black and white colors, unless there is a stringent constraint to emphasize some parts of the diagram by using distinguishable colors. In any case, it is always better to stick to the simplicity in terms of colors used, but if it is not the case, do not forget to detail the choice.
- Missing relationships between elements or isolated entities in a diagram might be a clue of incompleteness. From both a structural and behavioural perspective, every element or entity should rely on / have a relationship (represented by a line or arrow) with another part of the system represented by a different element.
- When using a label for an element in a diagram, it is recommended to not use any misleading or undocumented acronym which might cause confusions. Just a sequence of letters (e.g. TFH, RBPM) do not mean anything without a proper explanation on the diagram element or, even better, in the diagram legend (e.g. TFH - ticket feed handler, RBPM - rates business process manager).
- Another characteristic of naming diagram elements relates to extremely vague or generic terms (e.g. business logic, integration logic) which do not bring too much valuable information because their names are not properly self-descriptive. This issue might reside at the code level as well, and the suggestion would be to always use self explanatory and suggestive names by following on clean code principles.
- Architectural design is not related or fundamentally based on any technology, framework, programming or scripting language, IDE or development methodology. All of these come later on in the process in order to help build the architecture, but they are not the central point. They should not be included in the diagrams, but stated in the architectural description including the rationale around choosing them.
- Runtime elements (e.g. threads, processes, virtual machines, containers, services, firewalls, data repositories, etc.) are not present at compile time and it is recommended to avoid mixing these elements with the static ones (e.g. components, packages, classes) in the same diagram. There are dedicated diagram types (e.g. concurrency diagram, deployment diagram) which are primarily focused on runtime elements and it is important to distinguish between these two elements categories and to avoid mixing them as much as possible.
- Everything which is not described by the diagram itself is missing, and there is no room to provide verbal details to complement a diagram. Why? Because all explanations orally mentioned but not captured in the diagram are lost, and later on, when some other stakeholders (e.g. developer, architect) will read the diagram, they will not be aware of these explanations. Try to include all necessary details in a diagram to avoid any need for further clarifications.
- Adding elements related to different levels of abstraction in the same diagram might conflict, since they are seen from different perspectives. For example, adding components to an architectural context diagram or classes to a deployment diagram might diverge the purpose of the diagram itself. When creating a diagram, try to stick with the same level of abstraction.
- "Everything should be made as simple as possible, but no simpler" is a well known quote belonging to Albert Einstein. This is valid for architectural diagrams as well; the level and the granularity of captured information should be meaningfully elected. This is not an easy thing; it depends on the architectural model used, the experience of the architect and the complexity of the system.