Software architecture and design have always been an interesting topic to me. I always wonder how some of the largest real-world applications are designed, e.g. social media news feed, air ticket booking, ride-hailing booking.
The reason why I am interested in software architecture and design is that I want to build cool applications that can age well, with all the non-functional requirements such as secure, scalable, performant, maintainable checked.
However, this is an area that I think is lacking in software development, especially in small projects, because strict adherence to these principles requires an upfront investment of resources which is usually a luxury, or even something that is in the “don’t care” zone.
A Computer Science education introduces the concepts of SOLID via OOP, but its main focus is in computing fundamentals such as data structures and algorithms, networking, operating systems, database.
Whereas a full stack development bootcamp focuses more on the technologies for building modern applications.
After around 2 years in software development, with each system bigger than the previous one that I have worked with, I finally realized the importance of using a good system that is appropriate for the given project.
Learning about software architecture and design: Clean architecture
I started out by reading Clean architecture by Robert Martin(Unclde Bob).
Useful software design principles. The section on SOLID stood out the most for me as this is the meat of building maintainable softwares. However, will be lying if I said I understood everything at once.
It is through code review and discussions, reading code written by other people, that made this concept stick.
So far, SID out of SOLID, makes the most sense to me as I have practised them intentionally.
Domain driven design
Moving up a level, there is an architecture pattern called Domain Driven Design(DDD). It is a way of structuring complex applications that allow domain entities which contain important business rules to be protected from other parts of the application.
I have seen a bit of DDD in practice, but not have used it extensively yet.
Recently, I came across a series of articles by Khalil Stemmler on good software design, with proper code examples.
In the introduction to DDD, he introduces the benefits of DDD, which are discoverability and testability of code through proper encapsulation of domain entities, which ultimately leads to lower effort of maintenance in the long term.
The drawback is that there is a much higher investment of effort in the beginning, as compared to the anemic domain modelling, where almost no business logic lives in the domain entities, but in other places such as controllers or services.
Also, there are many more terms in DDD than anything else that I have come across so far: domain entities, repository, domain service, application service, controllers, aggregate, domain events, mappers, DTO.
I have not understood everything, especially aggregates and how they relate to domain events, which provide a separation of concern between services.
My understanding is that the controller is the infrastructure layer that is responsible for handling request and response. It is the gateway that other applications interface with.
The domain service encapsulates business logic that does not naturally fit into a asingle domain entity, and operates only on domain entities.
The application service operates on non-domain entities.
The repository retrieves from and saves data to the persistence layer
The domain entity, the meat of DDD, defines the business data and operations that we care about, in the true OO style.
It dawn on me that I have been following the anemic domain model in first 2 employments, which are justified because the teams are small(less than 10) and the projects are quite new(less than 2 years).
In fact, it was the right decision because low overhead of architecting the application meant that lesser time is needed to launch the project. However, it would be a sin if it were an enterprise project.
More resources on domain modelling
Here is a discussion of domain entities, the place where all business logic should reside, as long as it makes sense.
Here is a comprehensive discussion of repository and data mappers that demonstrates the application of single responsibility and encapsulation.
Refactoring guru is an awesome all-in-one resource that contains everything about refactoring, design patterns, SOLID principles. The website is well designed, with clear explanations and detailed examples, which serves as a handy guide and reference.
I have begun to see the benefits of DDD, especially in large applications. It builds on top of the SOLID principles and offers a way to build and maintain applications that are flexible to the evolving business requirements.