Goal: Make our code resilient against changes over time
A brief introduction to architecture
Software architecture is primarily the structure of the software components to be arranged in a purposeful and efficient system. The goal of software architecture is to minimize the human effort required to build and maintain software systems. One of the most effort-consuming processes in the software development cycle is to accommodate change. In software development, the primary method of handling change in the system is to create a separation of concerns between the layers of your software. This is where the Clean code architecture, created by Robert Cecil Martin (a.k.a Uncle Bob), shines.
Following are the benefits of implementing a clean code architecture with snippets from a node application.
Framework independence
Using the framework for a lot of operations can easily make our code heavily dependent on the framework we are using. Creating a tight coupling between our code and the underlying framework leads to difficulty in changing the framework in the future. For example, if you want to move from “express” to “sails”
To resolve this :
We limit our dependability on the framework, as much as possible.
We do this by using an adapter design pattern between the framework and our project’s code.
The same approach is used to adapt Response objects as well.
In a MERN stack application, we create an adaptRequest() function to act as an intermediary adapter between our express framework and application code i.e {code in the inner layers}. Check out my sample snippet below.
Database independent
We use a similar adapter design pattern to make your code {in the inner layers} independent of the database we are using.
Basically, we can create a DB service interface that consists of all generic database operations. Then implement a DB service for each type of database we want to use in your project. To give an example, suppose we have the requirement to use multiple heterogeneous databases(say DynamoDB and MongoDb) in a single project, we will create Db service for each of the databases we are using and simply pass the Db service(DynamoDbService.js) as a dependency injection to the service(say FileUploadService.js) that needs to perform the operation on that database(DynamoDB).
You can go a level deeper by passing the dbConnectionInstance as a dependency of the DB service. Thereby enabling you to make/switch DB connections within the project, by simply changing the dbConnectionInstance.
(I suggest doing so only if you have to connect to multiple db instances from a single application.)
Avoiding breaking changes due to third party libraries
Third-party libraries are often the cause of change in a project that has a longer development life span.
Everything from finding a better alternate library to upgrading the existing library may cause the code to be changed and often breaks the code.
Again our adapter design pattern can be implemented here to resolve this issue.
We simply create a Service (say ThirdPartyLib.js) and import third-party libraries in it and wrap the third-party function with your own function and append any extra logic if necessary. Then use this, ThirdParyLib.js, library wherever we need to use third-party methods.
Dependency injection
Dependency Injection, Dependency Injection, Dependency Injection — you have probably heard this word many times by now. But what is dependency injection?
‘Dependency Injection’ is a 25-dollar term for a 5-cent concept…Dependency injection means giving an object its instance variables. Really. That’s it. — [3]
Why do we use dependency injection in the first place?
Creating Testability
Dependency injection is a very useful technique for testing, since it allows dependencies to be mocked or stubbed out. [4]Achieving Loose coupling
The obvious benefit of loose coupling is that it provides the flexibility to change our dependencies without modifying the underlying business logic. This provides us with a greater ability to try out newer alternatives both during development as well as during testing without risking the changes in the code of the inner layers.
Creating clean code boilerplate
Although creating projects using clean code architecture has many benefits, creating the boilerplate code has always been an uphill task. The sample code you get online is great for learning purposes; however, creating a real-world application is significantly different from it. An easy way to do that is to use a new online code-generating platform called DhiWise.
You can add your models using the table view, click on build app, select clean code architecture from the combo box, and Boom!
Top comments (4)
Bro, Just use Nest.js
Was thinking exactly the same 😂
dont agree with both framework and database independence, i dont recall changing either of them on any project in the last decade
Wowsers, adaptRequest, seems like just about the dopiest thing ever!