#12 Document It: Architecture Decision Log
Capturing and storing architectural decisions can simplify the lives of future team members. We can keep a historical record of why certain architectural choices were made and at what time.
Documentation. Yikes!
This kind of thinking has been with me since the beginning of my programming career, and it's still the case today. I really hate it.
I recall when I had to describe architecture in a Word document and remember (:D) to update it every time it changed. It contained absolutely everything, from diagrams to concept descriptions and comments from other people. Usually, at the same time I was finishing it, it was already outdated.
Then, over time, I tried other alternatives, and the result was always the same—a lot of unstructured knowledge. Someone had to go through all the content just to find the relevant information obsolete.
Unstructured and obsolete are one of the biggest issues when it comes to managing knowledge.
Another problem is that you might encounter a situation in which you see that component X or pattern Y is present but makes no sense in your application.
Who the hack decided on this? It makes no sense!
Maybe it was just a mistake, but there is a chance that by the time it was added, it had solved some issues. However, you have no context other than repo history.
This is where the Architecture Decision Log can help.
It captures key architectural decisions made during the development of a software project and provides a historical record of why certain architectural choices were made and at what time. What’s important is that you don’t need any additional tools to build it.
How to create it?
I recommend keeping it as close to the code as possible; that’s why it is a good idea to create a folder next to your application (which can be in the root folder) named, e.g., architecture-decision-log:
Next, inside this folder, you will be adding a new Architecture Decision Record (ADR) each time you decide on anything related to architecture:
Adding, modifying, or replacing infrastructure components
Deciding for another architectural pattern
Using another logical pattern
And so on.
Each record is inside a separate file (in markdown, adoc, txt, or any other format). It is a good idea to numerate it starting from 0001:
Each record is immutable - if the decision needs to be changed, you just add another record with +1 numeration. This way, you can structure the log; anyone reading it will know it is ordered according to the timeline.
Each record contains a full description of the architectural decision:
Title
Date when it occurred
Problem description
Decision
Consequences of the decision
It is also a good idea to include an additional field called Considered alternatives, where you describe what other alternatives were discussed and why they were not selected. Such information can help in the future to understand not only the reasoning behind the decision but also why other approaches failed.
The cool thing about ADRs is that they are stored in the repository next to your code - there is no need to search for them elsewhere. When you implement a new feature requiring applying a pattern or changing a component, you can add a new ADR in the same commit you apply the change.
At some point, it becomes natural for everyone to think about ADRs whenever there is a new architectural decision. Thanks to it, you keep your architecture documentation clear, structured, and up-to-date.
Do you document your architecture? If so, how do you do that?
PS If you would like to see what other ADRs can look like, I invite you to look at our repository of Evolutionary Architecture.
It's a great idea, I've done something similar but in Confluence, it was easier to have a single page which you can browse at any time.