The MVC framework consists of Model,view,controller, where the execution process typically takes the data from the controller access model and renders the page through the view.
The MVC pattern is the basic pattern in web development, it adopts the layered design, and the responsibilities between the layers are clear. It backfired, however, that when we build on the MVC pattern over time, we will gradually feel the presence of adhesion and ambiguity between layers and layers, which is the important reason for the service layer to appear.
What's the problem?
To propose a solution, it is important to discover the nature of the problem. MVC pattern in the practice process, mainly facing the following several uncomfortable problems:
- The business logic is implemented directly on Layer C, which leads to:
- Different controllers, can not share common business logic, such as: discount calculation, anti-cheating judgment, which is bound to be unreasonable.
- Business logic upgrade, need to be directly in the original code modification compatible, resulting in the controller code is constantly expanding complex.
- Remote service protocol or call mode upgrade, need to find all the controller in the call point, modify each.
- DAO substitution (for example, migrating MySQL from Oracle) requires that all the controller's call points be found and modified individually.
- The business logic is implemented in the M-layer (Dao+model or ActiveRecord, below the model generic), which results in:
- Model assumes too much business logic, causing the business logic upgrade to need to modify the model, but the model's responsibility is not business, which is very contradictory.
- There is no problem in calling the business code in the 1 model, but which model manages the cross-table transaction?
- Business logic implementation in model, if the model is changed, then the business logic written in it is also copied into the new model, which is the cost of coupling.
I carefully recalled the previous MVC development pattern, which I have encountered and tried to solve, such as:
- To improve code reuse, I'll implement some common functionality as a separate tool class (check login) and provide a call in the controller.
- In order to provide the controller with business-related data, I realized in the ActiveRecord business-related additions and deletions to the controller call, more interesting is: Each table change the field, The way I re-generated ActiveRecord through the tools GII will cover my implementation, which is the cost of coupling.
The essence of the problem is that the business logic sticks to the C-layer and M-layer, and should be decoupled from the C-layer &m layer and become a separate service layer. Thus, in the C layer can be flexible replacement service to maintain a high degree of brevity, while the M-layer to maintain a single service to provide data only, service layer implementation of all complex business logic and common business logic.
The service layer's responsibilities
Based on the above analysis, service clips are logically divided into 3 categories, in the middle of the C and M Tiers:
- Model Side service: This is the encapsulation of each model of the business-related Common Data Interface , such as: Query orders. (I think: access to remote service acquisition data should also be attributed to this type of service)
- Intermediate Service: Encapsulates common business logic , such as calculating order discounts (which will use the service in 1).
- The service on the controller side: the service of the external interface is further encapsulated by services in 1, 2, and of course does not exclude direct access to DAO without using the 2 service (not recommended).
In practice, it should be natural to use these three types of service, after the understanding of these concepts and then the code design, will not be confused about the service's responsibilities, nature also has a new understanding of MVC.
About abstract
The controller calls "service on the controller side" to complete the business process directly, which means that the controller relies on which service class is specific.
The service calls "Dao/ar" to implement the database access, which means that the service relies on a specific "Dao/ar" class.
Service calls service, which means the service relies on a service class.
In order to remove this coupling, the general use of IOC dependency injection in the web domain is to implement "dependency inversion", both Java and PHP can implement this capability based on reflection, and each MVC framework has similar implementations.
is the service layer necessary?
A matter of opinion, I think long-time maintenance of large projects through a more granular layering, more conducive to the iterative upgrading of functionality.
For small and medium-sized projects, more than one layer means more code, but also in the design to consider the generality and versatility of the granularity of the problem, it is not as small as the brain to write a bit more redundant code.
More blogs please visit the Fish blog directly
On the meaning and responsibility of service layer in MVC framework