I learned spring and its layered structure(controller,service and dao)
@Controller("userController")
@service("userService")
@Transactional( propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = true)
@Repository("userDAO")
Now I am confused how do I make use of good OOPS practices (like this) with these layered structure to make a big project( real world have more complex business logic then sample applications usually provided). I also want to use these spring transaction and other features provided by framework. Can some please help me out with it or refer to open source project which clarifies my doubt.
An object-oriented layer architecture is composed of layers, forming a software or domain unit. The layers are organized hierarchically by the principles of generalization and specialization. The microstructures of their elements are classes or interfaces.
Implementing Layered Architecture One could try putting each layer in a separate Maven module, but then capturing the weird relationship between domain and persistence would not be easy. I usually stick with packages and use common sense along with code reviews to make sure that none of the rules are broken.
It is a simplified and automated version of the spring framework. The spring boot follows a layered architecture in which each layer communicates to other layers(Above or below in hierarchical order). The spring boot documentation provides the following definition to the Spring Boot Framework.
When to Use Layered Architectures. When developing simple, small applications, it is advisable to implement a layered architecture because it's the most simple framework. However, some developers are of the opinion that because they can be difficult to maintain, it is better to apply them to larger projects.
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.
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. :)
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 ofCustomerOrder
. 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..
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 theCustomer 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.
Spring application design and OOD are not mutually exclusive.
The typical Spring (MVC) application has the following structure:
@Controller
classes. These are the entry points of your application. They should not contain any business logic. Despite the name I identify them as the V in MVC (Model-View-Controller)@Service
classes. This is where you develop your business logic (BL). One of the benefit in putting your BL here is that it can be reused by multiple controllers (by a @Controller
and by a @RestController
for example). They are the C in MVC.@Repository
classes, where you implement your persistence layer (database, in-memory, whatever...). Additionally you can implement a set of @Component
s classes that describe your domain objects. These are the M in MVC.@Configuration
, @ControllerAdvice
and other Spring configuration/management classes.While designing each of these objects, you can follow whatever OOD approach you like.
In the OOD example you mentioned, I would design my application like this:
@Controller
) for each actor@Service
for each use case@Repository
and one @Component
for each domain classEDIT: you can find an example project I wrote for university here. It implements what I explained in the last three points with an additional layer (between @Controller and @Service) because there was a requirement to minimize dependencies on the C layer. The concepts still apply.
I think, you are asking a wrong question here. Layered architecture is inherently not object-oriented, and therefore, while using (some of) the object-oriented practices with it would be possible or even advisable, it should not by itself be the goal. It is akin to asking how do I use best truck driving practices to ride a bike.
Why am I saying that layered architecture is not object oriented? Well, as we know, there are three principles that distinguish object-oriented design: encapsulation, inheritance and polymorphism.
While the last two may or may not be present, depending on your design choices, layered architecture is, pretty much, the opposite of encapsulation: by nature of this approach, you explicitly separate your data ("DTOs") from your logic ("services").
Don't get me wrong, the fact that this approach isn't object-oriented doesn't mean that there is anything wrong with it. And vice versa, "object-oriented" isn't synonymous with "good", it's one of many tools in a programmer's toolbox, and, as with any tool, is better suited to solving some problems than others.
Layered architecture is a good design pattern, that can be successfully used to solve many real-life engineering problems. It has it's own set of best practices that can and should be used, and while that set may have some intersections with its counterpart from OOP, the two are certainly not equivalent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With