In nutshell
Layered architecture will just ease the code maintainability and consistence when it becomes huge and complex.
The fact to remember is that to do a proper software design before doing the implementation.
- Encapsulation - Business logic specific for a domain model should go inside it.
- Abstraction - Segregate the interfaces according to the grouping of services while writing the common business logic in the abstraction.
- Inheritance - Use when you are drafting your domain objects
- Polymorphism - Along with inheritance when you want to change the business logic of child models.
In detail
Below I'm trying my best to provide an example of an ERP application for this discussion. Hope an ERP is a sufficient big project to view the business logic complexity.
The below description is for any developer who need an idea to understand and make use of layered project structure in Spring (or any other framework).
But please note these are not rules to be followed but the best practices to be utilized. :)
1. Data Access Layer - Model /Domain Objects
This contains the mapping of actual tables to classes.
In an ERP example, this is where you get the models: CustomerOrder
, CustomerOrderLine
This also contains the en-capsuled logic of child domain objects and the domain logic of self. For example, the CustomerOrderLine
is a child of CustomerOrder
. The child cannot exists without the parent. So the parent will have the full control of building the childs within it. ie Business logic encapsulation.. ie: Add CustomerOrderLine
, RemoveCustomerOrderLine
etc.. And when it comes to self domain logic, ApproveCustomerOrder
, RejectCustomerOrder
etc..
2. Data Access Layer - Repository
This contains nothing but simple CRUD to database with SELECT, INSERT, UPDATE and DELETE SQLs
. You can use repository pattern in Spring along with Spring Data JPA
.
Key note: do not write any complex logic in this layer unless your logic is highly data intensive
In that case you might have to write one or more functions to do complex query statements. (Preferably in JPQL
)
In an ERP example, this is the place you write logic for GetCustomerOrders
, GetCustomerOrderByCustomer
, GetCustomerOrderLines
, GetOrderByStatus
In simple terms this layer defines how the application will communicate with the outside entities such as Database.
3. Service Layer
This is the place where you should put your complex business logic which involved Multiple unconnected (not child - parent) domain models. These will be reused in Web Controllers and Rest API Controllers.
So to maintain the consistence and to implement the security, I would prefer all the business logic even which were written in the domain models gets wrapped up at this layer.
In the ERP exmple this is the place you write the logic or wrap the logic which is written in Domain Model. For example CreateCustomerOrder
, ListCustomerOrder
, ApproveCustomerOrderLine
, ReleaseCustomerOrder
,...
In case if these logic should get executed along with other model logics, then those should be called at sequence within service layer as well. For example.
Misc Examples on complex business logic
If you want to create a Purchase Order
for your supplier, when the Customer Order
is released.
Then, this can be done by creating a service called SupplyChainService
binded using Spring AOP to the CustomerOrderService.ReleaseCustomerOrder
. In microservice design this can be done by a event published by Supply chain
domain microservice to a queue and get consumed by Customer Order
domain microservice
4. Controllers
Controllers can be categorized in two, namely: Web Controllers, and REST Controllers. No business logic should be implemented in this layer because the same logic can be required to call in Web as well as in API level.
In the ERP system, this is the place where you will write the controller for your customer order form to enter data and save it to create a new customer order.
This will be the place you will also create a API controller like REST to create the customer order via a mobile application or from a windows client.
Thanks to the SO community who showed me areas that I didn't cover on OOP principles in this answer
Edit
This is an answer when microservice is not too mainstream. Though it answered the OOP concepts, also look into CQRS based design as it's more common in modern micro service based architecture. Either way, you can incorporate OOP concepts regardless of what software architectural pattern you use.