DEV Community

DhiWise
DhiWise

Posted on • Edited on

Features of clean code architecture | Node.js

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 :

  1. We limit our dependability on the framework, as much as possible.

  2. We do this by using an adapter design pattern between the framework and our project’s code.

  3. 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

  1. Third-party libraries are often the cause of change in a project that has a longer development life span.

  2. Everything from finding a better alternate library to upgrading the existing library may cause the code to be changed and often breaks the code.

  3. Again our adapter design pattern can be implemented here to resolve this issue.

  4. 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?

  1. Creating Testability
    Dependency injection is a very useful technique for testing, since it allows dependencies to be mocked or stubbed out. [4]

  2. 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!

You can view the generated application’s code online or dl the source code.

Bibliography

  1. Clean Code — Uncle Bob entire series of lectures

  2. Dev mastery’s clean code architecture demo

  3. Howardamann’s clean code demo app

  4. Dependency Injection Demystified

  5. The clean code blog by Robert C. Martin (Uncle Bob)

  6. Discussion on DI over stack overflow

  7. Dhiwise-pro code platform

Top comments (4)

Collapse
 
talr98 profile image
Tal Rofe

Bro, Just use Nest.js

Collapse
 
marcel_cremer profile image
Marcel Cremer

Was thinking exactly the same 😂

Collapse
 
slidenerd profile image
slidenerd

dont agree with both framework and database independence, i dont recall changing either of them on any project in the last decade

Collapse
 
rmoskal profile image
Robert Moskal

Wowsers, adaptRequest, seems like just about the dopiest thing ever!