I recently received a question from one of my blog‘s readers, Ajay, and decided to share my answer here to help others with similar questions in mind.
Here’s the question from Ajay:
Hello David, I would like to know the difference btw the two types of MVC application architecture that I have come across recently:
1) The ones used in common spring MVC tutorials…model, view, controller, configs , DAO and resources.
2) A more elaborate architecture where app is divided into modules (eg. checkout, cart), each with their own package containing controller, service interface, service Impl and entity/model.
These two options are not mutually exclusive, in fact, they complement each other in well-designed web applications.
You can think of these two options as vertical and horizontal separations.
The reason for this separation lies in one of the most important design principles, Single Responsibility and the Abstraction design pattern.
The Abstraction design pattern introduces a layer of abstraction (eg: DAO layer) on top of a component (eg: database) while declaring a contract (interface) on how the rest of the application can communicate with that component through the abstraction layer.
This makes it easier to replace the underlying implementation of the contract (eg: your DAO layer today may use JPA, but tomorrow you could switch it to Elasticsearch or Neo4j with relatively small effort).
On the other hand, separation by modules (eg: checkout, cart) is based on business functionality.
That separation also relies on the Single Responsibility principle and the High Cohesion & Coupling principle.
Cohesion & Coupling
Cohesion is the degree of how components of a certain module belong together.
Coupling is the degree on how much components know about the internal workings of one another.
When you separate your modules into different packages based on business functionality, you make it easier for the future to refactor these modules into their own microservices (web applications). That way each of them can have their own deployment lifecycle and can be scaled independently.