Lessons learned from The Clean Architecture (Robert C. Martin).

Lessons learned from The Clean Architecture (Robert C. Martin).

Background

My journey into back-end development started in 2018 with learning how to build REST APIs using NodeJs and MongoDB. My idea of software architecture back then was the traditional Model-View-Controller (MVC) pattern (in my case, an MC pattern, since I was adopting an API approach, with my front-end being built using ReactJs). Typically, the Models contain the database schemas, while the Controllers contain the business logic required to make the application work.

As I grew, I got curious about how software was built on a large scale, and from my experience with the little projects I worked on during my development journey, I noticed that the MVC pattern was good—in the short term—for prototypes and projects that require urgent launch (e.g. Minimum Viable Products), but was not sustainable in the long run for medium and large scale projects, as it could incur technical debts, as well as some of the reasons listed below:

  • Tight Coupling: Key functional parts of the projects were tightly coupled to each other, with the business logic directly dependent on the models, which were directly dependent on the database. This setup made the entire software very brittle and difficult to change or add new features. A change to the type of database management system being used (SQL/NoSQL), for example, could cause issues and may lead to major parts of the business logic being rewritten, making this approach error-prone.

  • Difficulty in testing: Its tight coupling makes it difficult to perform unit & integration tests on the core business logic of the application.

The Clean Architecture

In May 2020, I learned about the Clean Architecture, proposed by Robert C. Martin. This architecture proposes a system of building software in which components of the system being built are loosely coupled. It applies the principle of separation of concerns and suggests that the core parts of the application i.e. critical business data (entities) and critical business rules (use cases) be separated from external components such as frameworks and databases. It treats these components as details that could be easily changed and hence should depend on the entities and use cases (and not the other way around).

Advantages

I applied what I learned by refactoring a project I built. Some of the advantages of this pattern I discovered are listed below:

  • Flexibility: The loose coupling that this architecture provides makes it easy to modify, as well as add/remove features. Components such as the database could be easily changed without affecting the core business object of the application. This also applies to the API strategy adopted. Transitioning from GraphQL to REST (or vice versa) could be handled without causing major issues in the application.

  • Framework agnostic: The architecture treats frameworks as a detail that could change. Hence, the choice of framework does not have a direct impact on the business object and ensures that the critical part of the application is protected from being tied to the framework used, along with related issues such as upgrades or changes in its API.

  • Easy to test: As a result of its loosely coupled nature, unit & integration testing can be carried out more efficiently. This helps with the adoption of test-driven development.

  • Reversible nature: It ensures that the entire application is more manageable, as well as aid the transition from a monolithic architecture to a microservice architecture (and vice versa) if the need arises.

Tradeoffs

An important aspect of decision-making in software engineering is considering the tradeoffs of decisions being made during the development process, and the impact of such tradeoffs on the system being built.

A high tradeoff that comes with adopting the clean architecture pattern is setting up the project structure. The decoupled nature of the architecture translates to sectioning the overall software into several smaller components. The process of orchestrating these small components to function as a whole would require some effort and might be a bit time-consuming.

As a result, I would recommend that this architecture be adopted for medium to large-scale projects.

Conclusion

The clean architecture provides an array of benefits to software applications, as we’ve seen so far. It takes more effort to implement when compared with the traditional approach, but it’s definitely worth it.