How to Prepare a Design Review Like an Expert?
Tags: tutorial, programming, productivity, design
Published: 2022-02-28 08:40:28

> This article will take backend development as an example, but the same concepts can be applied to various fields.

Before explaining how to prepare a good design review, let's first introduce what a design review should have. As an architect, I'm going to tell you what I want to see.


1. [C4 model](https://c4model.com/)
2. [User stories and use cases](https://betterprogramming.pub/how-to-design-in-clean-architecture-way-part-2-8524e76f2720)
3. Design decisions

As an architect, what I want to see the most is the above three items, not code flow nor database schema even nor RESTful API spec.

And the most important of them is the C4 model.

## C4 Model

Why is the C4 model so important? Before explaining, let's briefly introduce the C4 model.

The C4 model contains four **C**s.

1. Context: This is an overview of the system that describes how users interact with whole system. It will be displayed from the user's view, so the details of the system will not be showed.
2. Container: Containers here do not refer to container virtualization like docker. A container in the C4 model refers to an entity that can be deployed separately, such as API server, database, message queue, etc.
3. Component: Components are the modules under a container. It contains the interaction between modules or the association between domains in the domain-driven design.
4. Code: The last is the source code under the component. But when describing the architecture, we will not show the details of the code, it is enough to be able to describe the relationship between objects.

From above description, the purpose of the C4 model is to explain interactions and relationships within the system. From the largest unit, user interaction, to the interaction between objects and objects, these interactions help architects get a complete picture of the entire system and know if such interactions are appropriate.

For example, a small application might look like this from the container's perspective.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19bjivceo0up1c57bg9k.png)

Some developers may think that such a diagram is too simple, however, such a simple diagram is enough for architects to discover possible problems.

1. Scalability: When the number of users increases, is there any way for the API to handle it? Even if API can satisfy the throughput, what about the database?
2. Reliability: When the API crashes, is there a risk of a SPOF (single point of failure)?
3. Efficiency: When the amount of data increases and the response time of the database becomes slower, how will users feel?

Such non-functional requirements can be analyzed from a relationship diagram. The above are just a few common non-functional requirements, see the full list in [wiki](https://en.wikipedia.org/wiki/Non-functional_requirement).

Then, take the perspective of components as an example. A simple social media might be as follows.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7eg1592jdvf1zqegypy.png)

This is also a very intuitive diagram. It looks like it just lists the various modules. Is such a diagram really worth it?

Yes. Absolutely.

When we assess the degree of coupling of an architecture, we usually use `instability` as an indicator.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wlkgiccs3crso0pmf3f.png)

`Ce` refers to the number of afferent couplings and `Ca` refers to the number of afferent couplings. The closer to `0` the more stable the module is, and vice versa. Regarding coupling, [I have an article](https://betterprogramming.pub/temporal-coupling-in-code-e74899f7a48f) that specifically describes the problem of coupling.

For this social media, its `instability` of Recommendation module is `0.8`. This means that the recommendation is unstable. As long as any dependency module is modified, no matter the interface or behavior, it will directly or indirectly affect the recommendation system.

The architect analyzes the entire architecture through such a simple diagram. Based on different fields and different architectures, there will be completely different decoupling methods. Without a complete view of the existing architecture, the architect can only provide some innocuous comments.

## User stories and use cases

How to write good user stories and use cases I have covered in [previous article](https://betterprogramming.pub/how-to-design-in-clean-architecture-way-part-2-8524e76f2720).

In this section I just echo the C4 model above. In fact, the user story also corresponds to the context in the C4 model. To have a good story, there is a way to draw the correct context.

## Design decisions

Design decisions are at the heart of the entire design review. The whole design review is about examining whether each design decision is the right one. The C4 model, user stories and use cases mentioned earlier are only meant to provide background information for the whole review, in order to understand the meaning and risks behind each decision.

But what is the design decision?

It feels like a simple word, but in practice it is hard to feel it. So I offer a simple formula:

> Why do *A* (instead of *B*)?
 
For instance,

1. Why use MySQL instead of MongoDB?
2. Why use cache? (instead of accessing the database directly)
3. Why use the synchronous restful API instead of the asynchronous CQRS?

The questions mentioned above are a bit broad, so let's continue to narrow them down.

1. Why do we want the recommendation system to use synchronous calls to get data from the post system?
2. Why is this function split into two sub-functions?
3. Why is this line of source code written like this?

Have you noticed? It's all design decisions, from system orientation to the reason for each line of code, except that in a design review you may not actually be asked what the reason for each line is. Thus, what kind of decisions should be brought up for discussion?

My opinion is that the first three **C**'s of the C4 model are worthy targets for discussion. By writing down the C4 model and listing the purpose and reason for each line and block, architects will be able to identify potential problems and hidden risks among the many functional and non-functional requirements.

As for the last **C**, code, let's leave it to the developers to find out during the code review.


## Conclusion

This article explains the three main items of a good design review. The C4 model gives the architect a quicker overview of the system; then the user stories and use cases that the feature will address so that the architect understands what the functional requirements are; and finally the developers' design decisions so that the architect knows the trade-offs behind each decision.

In this way, everyone is on the same page. The architect can make his recommendations and point out the risks behind the system, and the developers can understand the direction of the system's evolution and the problems that need to be solved.

It's important to remember to provide enough information so that the architect can make the right recommendations, otherwise you'll just get hot air.

---

In my previous articles I have actually explained the different design decisions, hoping that the analysis will make you aware of where decisions need to be made and how they should be made.

- Why do we need to define a repo?  [Dependency Injection](https://medium.com/interviewnoodle/whats-difference-between-unit-test-and-integration-test-aae6ef13220)
- Why do we need layers? [Layered Aechitecture](https://lazypro.medium.com/layered-architecture-clarification-e55b69d60e98)
- How to evolve a system? [Shift from Monolith to CQRS](https://medium.com/interviewnoodle/shift-from-monolith-to-cqrs-a34bab75617e)
- How to decouple? [Event-driven architecture](https://betterprogramming.pub/temporal-coupling-in-code-e74899f7a48f)