Discovering the Intent with Different Flavors of Architecture Decision Record

Mufrid Krilic
5 min readApr 30, 2022

--

Whenever presented with an overview of a software system, I become rather curious about the reasoning that led to the decisions behind the current state of the system. Traditionally, the system overviews are depicted as a diagram of some sort, and as such represent a snapshot in time highlighting the existing elements in the system and the relationships between them. Even if there are traces of system behavior in the diagrams, which goes some way towards giving a more complete picture about the system and the reason for its existence, it is still the current state-behavior we are observing.

Getting the system in a certain state obviously involves some decision-making which could be hard to discern just by looking at the diagrams. In my experience, the history of decisions tells much about the system and about the team that evolved the system. Among many different takes on the meaning of the term Software Architecture, the Gregor Hohpe’s perspective of important design decision resonates particularly well in this context. In that regard any kind of system overview depicting the current state of the system represents the “How” and “What” dimensions, while a decision log is more concerned with the “Why” dimension of the software architecture.

What decisions did designers from ancient Rome consider while constructing the Pantheon?

Having embraced this approach in the teams I have been a part of, we invested some time trying to document the reasoning behind the design decisions. Usually we would get into the discussion on code vs. diagrams and which approach actually would serve the purpose the best way. On the one hand, it was clear that a complex code base with a plenty of relationships between source code structures is neither easily browsable nor comprehendible. On the other hand, whenever we attempted some kind of alternative visualization of the system relationships it turned out not to be used and would quickly deteriorate.

Architecture Decision Record

That led us to try the much recommended Architecture Decision Record (ADR), introduced by Michael Nygard, as a part of our development routines.

We tried to write the ADR as a simple text document at the beginning of a project and maintain it during the project. Apart from requiring discipline to maintain the ADR whilst the software product is being evolved, one of the major issues was that it seemed unclear to the team what decisions needed to be documented!

Knowing what are the actual significant architectural decisions at the time of making a decision was not immediately obvious

The community advice is to look for the irreversible decisions or decisions that are hard to change. What presented the challenge however, were design choices that did not seem to manifest themselves as “hard to change” yet over time they turned out to be the foundation of product design that emerged. Examples that spring to mind are the domain model entities that end up with lots of dependencies pointing towards them, or the decision not to preserve domain boundaries on the front-end. Both decisions seemed to be something that could be adapted down the road yet the system evolved along these lines nevertheless.

It became clear that, on top of trying to find the appropriate format for the ADR, we simultaneously struggled with the content of the decision log itself. To address this, we agreed to postpone creating the ADR to allow for the product to evolve and mature for some time. The optimal time for establishing the ADR could coincide with some project milestone or with collecting feedback from the testing or real usage. The latter could even help in figuring out what decisions turned out to be the significant ones.

This approach paid dividends. Not only were we able to reason about the decisions that deserved being documented in the ADR, we were at the same time positioned to document the evolution of the system.

By documenting the ADR in the retrospect we could draw on the timeline how our comprehension of the system and the domain evolved. We could more easily distinguish what decisions led to the system being in the current state and hence document the learning that occurred in the team.

This way, discovering the most important parts of the system was rather straightforward because we could quickly relate to the discussions which were either very intense or loaded with very different perspectives within the team. The parts of the system discussed thus “deserved” being mentioned in the ADR and one could argue that discovering this up-front could have led to different conclusions.

The format of the ADR itself went through some changes along the way. We started with just writing a short summary with the main ideas behind the system design, checked with the rest of the source code. This option was attractive as it required little time to establish the ADR and the need for maintenance of the ADR was rather limited.

Gradually we expanded this with visualizations as diagrams of different kinds. We ended up with having ADRs created exclusively on Miro boards which allowed us to combine the visual format with textual comments placed in a visual context. This approach consisted of multiple Miro frames on the board each dedicated to different stages of the evolution of the system, and as such effectively documenting a history of the system.

ADR - different flavors

To further preserve the perspective of documenting the system evolution as the ADR, a team working agreement could specify that every source code commit message should explain why the commit is the way it is, not only what it contains. One simple way of achieving this is asking that each commit comment should contain the word because!

This way the commit history would outline different stages as the project progressed, and thus could reveal the decisions that drove the changes in the system. Some tool support would be preferred to reduce the time-prone effort to browse through the commit history.

Going even further, could this discussion be a case for comments in code? It is an age-long discussion on whether or not to include comments in the source code, yet if we want to document the intent behind the code, the comments would allow for more contextual explanation along the usual best practices of clean code.

Wrapping Up

This post suggests creating ADRs in retrospect, documenting the intent and the reasoning behind the decisions, after the decisions have been taken and the effects of the decisions have been observed. In my experience, this helps documenting the system architecture in a clear way and avoids the dilemma on distinguishing the significant decisions from the less significant ones.

One of the more direct benefits of ADRs in general is lowering the threshold for understanding the system itself. The legacy systems benefit greatly from this. The more time that has passed since the development on the system has been “idle” the easier will be for the team to pick up where it had left off or for the organization to transfer the ownership to another team.

Onboarding of new team members is another case where ADRs are of great use. In case you don’t have an ADR in place yet I would suggest to start creating one during the onboarding process and thus interactively engage both the incumbent and new team members in the process!

--

--

Mufrid Krilic

Domain-Driven Design Coach and one of Coworkers at CoWork, Norway. First Lego League mentor. My views are my own. Speaking gigs: https://sessionize.com/mufrid/