By Gian Zas

The importance of introducing periodic architecture design reviews in your code review process.

Stagnant design

As a product evolves over several development cycles its design may become outdated. The design that seemed good enough during the first iterations may not be appropriate, as your understanding of the project and the underlying technology changes.

Indeed, after several iterations, some design decisions that seemed reasonable during the early stages degrade over time. As a consequence, adding new features and maintaining the product start to become increasingly costly and error-prone.

Only focusing on small and gradual changes, instead of challenging the high-level architecture, may generate unexpected issues, including cyclic dependencies between modules, duplicated responsibilities, unmanaged remote calls and cross-boundary violations.

Design as an evolutionary process

In an agile context, embracing change is a universal principle. We adapt to changes in requirements, priorities, processes, technology and so on. It’s unlikely that the initial design of a software product will remain acceptable after the surge of changes that a product faces during its entire life cycle.

Given that software architecture design is part of a product, it must continuously evolve in order to adapt to these inevitable changes that happen during the life of every project. If the software architecture remains invariant throughout the development process, then the quality of the final product – including qualitative factors, like correctness, efficiency, accuracy, maintainability and flexibility – will most likely be diminished.

You can’t see the forest for the trees

When you start coding a new user story, you normally put yourself into ‘coding mode’ and start introducing changes to the existing codebase, taking the existing architecture design for granted. Sometimes, you need to stretch the boundaries of the architecture a little, but generally you are more focused on the immediate goals and lower-levels of abstraction.

Even when you are in the refactoring stage within the Test Driven Development (TDD) red-green-refactor cycle, the underlying system architecture often remains unchanged. When another team member reviews the changes you have made to the codebase, the tendency will naturally be to focus in on the code being reviewed, and not to question the overall architecture. The reason for this is that, neither the TDD’s refactoring steps, nor conventional code reviews focus on architecture design.

For example, let’s suppose we need to store two values that are very unlikely to change over time. Based on this assumption, the team decides to store them in a configuration file. Weeks later, the client realizes that it may be useful to allow a superuser to change these values via an admin panel. In response to this, the team decides to create a table to store these two values. Some time later, more and more configurable values are progressively required to be stored in the database. The team starts adding new columns to the table, but there’s a threshold beyond which the model becomes unmaintainable. At that point, it might be a better idea to step back, review the architecture design and introduce a key-value based structure. It is difficult to effect changes if you are just focused on reviewing the code.

The sensation that something is going wrong with the architecture design may arise during regular code inspections. However, having periodic architecture design reviews allows the team to identify any problems, propose solutions and define a refactoring plan.

The whole picture

To incorporate incoming changes, the architecture design must first be inspected from a bird’s-eye view. Only by inspecting it in such a way will we observe dependencies between packages, classes and objects. This perspective allows to uncover design problems and elaborate what design refactoring is needed to improve the architecture.

This point of view is generally not taken into account when the team is in coding mode. The code-refactor approach and the ideas that emerge from taking a more global perspective are normally richer than those coming out of a typical TDD cycle.

Introducing Architecture Design Reviews into a project

Architecture Design Reviews (ADRs) are complementary to conventional code reviews. The goal is, periodically, to assess the state of the system’s architecture design, to identify problems and opportunities for improvement, to propose solutions and to discuss an action plan.

If the project has already started, and the idea of having periodic ADRs hasn’t been considered before, then a Retrospective meeting is probably the best place to propose the idea. The team can decide whether it is convenient to dedicate some time during the next sprint to an ADR and which members of the team will participate in the review.

 

Architecture Design Review flow
Architecture Design Review flow

 

The first ADR starts by creating the architecture design diagrams, to catch up with the current state of the product.

The first step in syncing the diagrams with the underlying code is to draw the codebase component and package diagrams.

The resulting diagrams don’t need to conform with the UML specification. The whole point, is that the team can all recognize and understand the system architecture, so they can communicate using a common language.

By reviewing the diagrams, other team members can spot design problems and collaborate in a more efficient way.

If needed, the team can drill-down when reviewing these diagrams to review any hot spot in the codebase, without losing focus on the big picture.

After identifying a list of design issues, the review team can decide which to tackle first. In the best case, if the list is short, they can decide to tackle them all.

The next step is to discuss different solutions for each issue and agree on an action plan for actually refactoring the codebase. For any issues that are not too complex, the solutions can be implemented during the ADR. More complex changes should be converted into a user story and uploaded to the product backlog.

Any changes to the codebase must be reflected back in the original diagrams. Having a shared and accessible place to store and update the diagrams is good practice. It doesn’t have to be too sophisticated: some sharpies, post-its and a wall can do a perfectly good job. However, it is important that the diagrams are kept updated. Outdated documentation is worse than not having any documentation, at all.

Guidelines for Architecture Design Reviews

If the team finds that the review has been helpful they can start to incorporate it into the development process.

Four tips on how to conduct Architecture Design Reviews:

  • Set how often you perform design reviews. Some teams choose to hold monthly reviews, while others prefer to hold reviews every two months.
  • It is not necessary for the whole team to participate in every review. A pair of developers can be perfectly sufficient to carry out a review, successfully. It is recommended that one of them be an experienced developer.
  • Rotate the review team. The whole team should be accountable for the system architecture.
  • Make any required design changes during the current sprint. Only the first ADR should be see a significant number of changes. If the team undertakes regular reviews, the extent of the changes should decrease over time.

Sustainable pace

Carrying out regular Architecture Design Reviews prevents big code rewrites, helping programmers focus on creating user stories rather than struggling with the design. As a consequence, regular ADRs increase the odds that each sprint stays within the estimated deadline and allow the development velocity to be more predictable.

Empowering all team members to identify problems, propose solutions and implement regular design reviews reduces the risk of miscommunication and fosters product ownership and commitment.

Improving the system’s architecture design helps increase the product’s reliability and reduce the technical debt.