How do you maintain a growing code base? Don't you agree with the increase code base it increases complexity too? As the code base grows it becomes really difficult to keep code structured and cleanly organized. There is always the risk that modifying existing software will result in unexpected problems, unmet objectives, or both which is also known as Software entropy.
There are numerous software designs that recommend different approaches to software development. Hexagonal Architecture, Screaming Architecture, DCI, and other architectural styles are examples. The separation of concerns is something that all of these designs have in common. That is, they separate various functionalities into various layers and delegate responsibility to each layer. Robe is based on all of these architectures. Based on all these architectures, Robert Martin a.k.a “Uncle Bob” has synthesized an architecture known as the “clean architecture”.
What is Clean Architecture ?
Clean architecture is a layered software architecture. Different layers of clean architecture are as follows:
- Models : Models are representation of real world entity which are mapped as tables in database. Here i have used Go Lang as a example language. Clean architecture is not a langugae specific thing rather it is a design pattern.
Snippets :
//Post Post Model
type Post struct {
ID int64 `gorm:"primary_key;auto_increment" json:"id"`
Title string `gorm:"size:200" json:"title"`
Body string `gorm:"size:3000" json:"body" `
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
}
Repository Layer : Repository layer is responsible for performing database CRUD operations. Snippets of how repository layer looks like. Snippet :
//Save -> Method for saving post to database func (p PostRepository) Save(post models.Post) error { return p.db.DB.Create(&post).Error }
Controller Layer : Controller layer is responsible for getting api requests (input) and return the response.
// AddPost : AddPost controller func (p *PostController) AddPost(ctx *gin.Context) { var post models.Post ctx.ShouldBindJSON(&post) if post.Title == "" { util.ErrorJSON(ctx, http.StatusBadRequest, "Title is required") return } if post.Body == "" { util.ErrorJSON(ctx, http.StatusBadRequest, "Body is required") return } err := p.service.Save(post) if err != nil { util.ErrorJSON(ctx, http.StatusBadRequest, "Failed to create post") return } util.SuccessJSON(ctx, http.StatusCreated, "Successfully Created Post") }
Service Layer : Service layer acts as bridge between Repository and Controller layer. The parsed input from Controller layer are passed to Repository Layer via Service Layer :
//Save -> calls post repository save method func (p PostService) Save(post models.Post) error { return p.repository.Save(post) }
Here is a overview of how the structure looks :
├── api
│ ├── controller
│ │ └── post.go
│ ├── repository
│ │ └── post.go
│ ├── routes
│ │ └── post.go
│ └── service
│ └── post.go
├── docker-compose.yml
├── Dockerfile
├── go.mod
├── go.sum
├── infrastructure
│ ├── db.go
│ ├── env.go
│ └── routes.go
├── main
├── main.go
├── models
│ └── post.go
└── util
└── response.go
Advantages of Clean Architecture
Eases Communication : With an early emphasis on establishing a common and ubiquitous language related to the domain model of the project, teams will often find communication throughout the entire development life cycle to be much easier. Typically, Clean Architecture will require less technical jargon when discussing aspects of the application, since the ubiquitous language established early on will likely define simpler terms to refer to those more technical aspects.
Improves Flexibility: Since Clean Architecture is so heavily based around the concepts of object-oriented analysis and design, nearly everything within the domain model will be based on an object and will, therefore, be quite modular and encapsulated. This allows for various components, or even the entire system as a whole, to be altered and improved on a regular, continuous basis.
Here is repository that applies the clean architecture Implementation of Clean Architecture can be found here Another really good article implementing clean architecture
Conclusion
It might not be easy first to implement clean architecture to your project, but when you have to change some aspects of your application or add new features, this really helps and you will thank yourself for following good architecture patterns for your application. Following clean architecture for all kind of projects is not mandatory. Following clean architecture on small projects make it more complex.
Thank you for reading !