Architectural Decisions
If you ask software practitioners what the most visible output is from architectural activities, many will likely point to a fancy diagram that highlights the key components and their interactions. Usually, the more color and complexity, the better. The diagram is typically too difficult to read on a normal page and requires a special large-scale printer to produce. Architects want to look smart, and producing a complex diagram shows that the architect can solve extremely difficult problems! Though such diagrams give the authors and readers the false sense of being in control, they normally have limited impact on driving any architectural change. In general, these diagrams are rarely understood in a consistent manner and provide limited insight without a voiceover from the diagram’s author. In addition, diagrams are hard to change, which ends up in a divergence from the code running in the production environment that adds confusion when making architectural decisions.
This brings us to the question, What is the unit of work of an architect (or architectural work)? Is it a fancy diagram, a logical model, a running prototype? Continuous Architecture states that the unit of work of an architect is an architectural decision. As a result, one of the most important outputs of any architectural activity is the set of decisions made along the software development journey. We are always surprised that so little effort is spent in most organizations on arriving at and documenting architectural decisions in a consistent and understandable manner, though we have seen a trend in the last few years to rectify this gap. A good example is the focus on architectural decision records in GitHub.5
In our original book,6 we discussed in detail what an architectural decision should look like. Following are the key points:
It is important to clearly articulate all constraints related to a decision—architecture is, in essence, about finding the best (i.e., good enough) solution within the constraints given to us.
As stated in principle 2, Focus on quality attributes, not on functional requirements, it is important to explicitly address quality attribute requirements.
All options considered and rationale for coming to the decision have to be articulated.
Tradeoff between the different options and impact on quality attributes should be considered.
Finally, the following information is critical for an architectural decision: Who made this decision, and when? Appropriate accountability increases the trust in the decisions being made.
Making and Governing Architectural Decisions
Let us look at the different types of architectural decisions in an enterprise. Figure 2.3 demonstrates our recommended approach to making architectural decisions in a typical enterprise.7
Figure 2.3 Levels of architectural decisions
If we assume that an enterprise has set up governance bodies that ratify decisions, it is only natural that the higher up you go, the fewer decisions are made and the fewer reviews are conducted. For example, enterprise architecture boards make far fewer decisions than product-level governance boards. Note that the scope and significance of architectural decisions also increase with scale. However, most decisions that can impact an architecture are driven on the ground by development teams. The closer you get to implementation, the more decisions are made. Although they tend to be of a more limited scope, over time, these decisions significantly impact the overall architecture. There is nothing wrong with making more decisions at this level. The last thing we recommend is to create unnecessary burden and bureaucracy on development teams that need to be agile; they must quickly make decisions to deliver their software system. From a Continuous Architecture perspective, two elements enable us to take advantage of aligning agile project teams to wider governance around architectural decisions:
Guidelines: In reality, the probability of development teams compromising the architecture is greatly reduced if they are given clear guidelines to adhere to. For example, if there are clear guidelines around where and how to implement stored procedures, then the risk of creating a brittle architecture by writing stored procedures in random parts of the architecture can be avoided.8 If you go back to Figure 2.3, you see that the main job of higher governance bodies is not to make decisions but to define guidelines. The recommended approach is that there should be fewer principles the higher you go in the organization.
Visibility: As stated before, we do not want to stop teams from making decisions aligned with their rhythm of delivery. At the same time, we do not want the overall architecture of a system or enterprise compromised by development team decisions. To go back to our stored procedure example, we can imagine a scenario where teams put a stored procedure here and there to meet their immediate deliverables. In some cases, even the existence of these stored procedures can be forgotten, resulting in a brittle architecture that is expensive to refactor. Creating visibility of architectural decisions at all levels of the organization and sharing these decisions among different teams will greatly reduce the probability of significant architectural compromises occurring. It is not technically difficult to create visibility; all you need to do is agree on how to document an architectural decision. You can use a version of the template presented in our original book or utilize architectural decision records. You can utilize existing communication and social media channels available in the organization to share these decisions. Though technically not difficult, creating the culture for sharing architectural decisions is still difficult to realize, mainly because it requires discipline, perseverance, and open communication. There is also a natural tension between having your decisions visible to everyone but at the same time close to the team when working (e.g., checked into their Git repository).
Let us look briefly at how the Continuous Architecture principles help us in dealing with architectural decisions. These principles are aligned with Domain-Driven Design,9 which is an extremely powerful approach to software development that addresses challenges similar to those addressed by Continuous Architecture.
Applying principle 4, Architect for change—leverage the “power of small,” results in loosely coupled cohesive components. The architectural decisions within a component will have limited impact on other components. Some architectural decisions will still cut across components (e.g., minimally how to define the components and their integration patterns), but these decisions can also be addressed independently of component-specific decisions.
Applying principle 6, Model the organization of your teams after the design of the system you are working on, results in collaborative teams that focus on delivering a set of components. This means that the knowledge sharing of relevant architectural decisions is more natural because the team is already operating in a collaborative manner.
Architectural Decisions in Agile Projects
Let us now investigate architectural decisions within the context of agile development. Most technology practitioners are wary of high-level architectural direction from the ivory tower. The team will make the necessary decisions and refactor them when the need arises. We are supportive of this view. Continuous Architecture emphasizes explicitly focusing on architectural decisions rather than forgetting them in the heat of the battle: architectural decisions should be treated as a key software artifact. Making architectural decisions an explicit artifact is key for agile to scale to and link with the wider enterprise context.
By clearly defining all known architectural decisions, we are basically creating an architectural backlog. This list includes the decisions you have made and the ones you know you have to make. Obviously, the list of architectural decisions will evolve as you make decisions and develop your product. What is important is to have a list of known architectural decisions and decide on which ones you need to address immediately. Remember principle 3, Delay design decisions until they are absolutely necessary.
There are two main ways in which you can integrate your architectural decisions with your product backlog. One option is to keep the architectural decision backlog separate. The second option is to have them as part of your product backlog but tagged separately. The exact approach you take will be based on what works within your context. The key point is to not lose track of these architectural decisions. Figure 2.4 illustrates how the architectural decision backlog logically relates to individual product backlogs.
Figure 2.4 Architectural decision and product backlogs
If you take a risk-based approach for prioritization, you will end up focusing on architecturally significant scenarios first. Then your initial set of sprints becomes focused on making key architectural decisions.
If you then make your architectural backlog visible to other teams and relevant architecture groups, then you have created full transparency into how you are evolving your architecture.
Although focusing on architectural decisions is an essential activity, it is still necessary to create a level of architectural description to communicate and socialize the architecture. We believe that more than 50 percent of architecture is communication and collaboration. You need such to be able to train new team members as well as explain your system to different stakeholders. Communication and collaboration are addressed in detail in the original Continuous Architecture.10
As we expand on our case study in subsequent chapters, we highlight key architectural decisions. These are examples and are not meant as a full set of decisions. In addition, we capture only some basic information for each decision, as exemplified in Table 2.1. For most architectural decisions, we expect that more information is captured, including constraints and detail regarding analysis and rationale.
Table 2.1 Decision Log Entry Example
Type |
Name |
ID |
Brief Description |
Options |
Rationale |
---|---|---|---|---|---|
Foundational |
Native Mobile Apps |
FDN-1 |
The user interface on mobile devices will be implemented as native iOS and Android applications. |
Option 1, Develop native applications. Option 2, Implement a responsive design via a browser. |
Better end-user experience. Better platform integration. However, there is duplicated effort for the two platforms and possible inconsistency across platforms. |