Why does Ali suggest adding an additional Manager layer to the MVC three-tier architecture

When we first became programmers, we were "educated" by our predecessors that the design of the system should follow the MVC (Model-View-Controller) architecture. It divides the overall system into three levels: Model (model), View (view) and Controller (controller), that is, it isolates the user view from business processing, and connects them through the controller to achieve a good performance. The decoupling of logic and logic is a standard software layered architecture.

MVC three-tier architecture

The MVC layered architecture is the simplest layered approach in architecture. In order to follow this layered architecture, we often create three directories when building projects: controller, service, and dao, which correspond to the presentation layer, logic layer, and data access layer respectively.

Schematic diagram of three-tier architecture

The role of each layer is as follows:

  • Controller layer: It mainly forwards access control, checks various basic parameters, or simply processes non-reusable services.

  • Service layer: mainly deals with business logic and transactions

  • Dao layer: responsible for data interaction with the underlying database MySQL, Oracle, etc.

However, as our business logic becomes more and more complex and more and more codes are written, the problems of this simple three-tier architecture become more and more obvious.

Disadvantages of MVC architecture

The traditional MVC layering has the following obvious problems:

  1. Service layer code is bloated

  2. The Service layer is prone to large transactions and nested transactions, resulting in many problems, and it is extremely difficult to troubleshoot

  3. The dao layer is mixed with business logic

  4. The sql statement of the dao layer is complex, and there are many associated queries

In order to solve this problem, I refer to the "Alibaba Java Development Manual", and separate a general business processing layer (Manager layer) under the Service layer

Manager layer

In this layered architecture, the Manager layer is mainly added, and its relationship with the Service layer is: the Manager layer provides atomic service interfaces, and the Service layer is responsible for arranging atomic interfaces based on business logic.

Characteristics of the Manager layer

The Manager layer is described in the "Alibaba Java Development Manual" as follows:

Manager layer: general business processing layer, which has the following characteristics:

  1. For the layer encapsulated by the third-party platform, preprocess the returned result and convert the abnormal information, and adapt the upper layer interface;

  2. The sinking of the general capabilities of the Service layer, such as caching solutions and general processing of middleware;

  3. Interact with the DAO layer and reuse the combination of multiple DAOs.

In actual development we can use the Manager layer like this

  1. For complex business, the service provides data to the Manager layer, is responsible for business arrangement, and then sinks the transaction to the Manager layer. The Manager layer does not allow mutual calls, and there will be no transaction nesting.

  2. Focus on sql language without business, or dao layer encapsulation of general business at the manager layer.

  3. Avoid complex join queries. The pressure on the database is much greater than that of Java, so SQL must be strictly controlled, so it can be split at the manager layer, such as complex queries.

Of course, for simple businesses, the Manager layer may not be used.

Manager layer use cases

Here we give an example to illustrate the usage scenario of the Manager layer:

Suppose you have a user system, which has an interface for obtaining user information, which calls  getUser the methods of the logical Service layer, getUserand the methods  User DB interact with each other to obtain data. The part shown on the left in the figure below.

At this time, the product puts forward a requirement. When displaying user information in the APP, if the user does not exist, a user should be automatically created for the user. At the same time, to create an HTML5 page, the HTML5 page must retain the previous logic, that is, there is no need to create a user.

At this time, according to the traditional three-tier architecture, the boundary of the logic layer becomes unclear, and the presentation layer also undertakes part of the business logic, because we often add business logic processing in the presentation layer Controller, which will acquire users and create user interfaces. choreographed.

After adding the Manager layer, the Manager layer provides interfaces for creating users and obtaining user information, and the Service layer is responsible for assembling these two interfaces. In this way, the business logic originally distributed in the presentation layer is unified into the Service layer, and the boundaries of each layer are very clear.

Next, let's look at a piece of actual code to explain how to distinguish between the Service layer and the Manager layer?

@Transactional(rollbackFor = Throwable.class)
public Result<String> upOrDown(Long departmentId, Long swapId) {
  // 验证 1
  DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
  if (departmentEntity == null) {
    return Result.error("部门xxx不存在");
  }
  // 验证 2
  DepartmentEntity swapEntity = departmentDao.selectById(swapId);
  if (swapEntity == null) {
    return Result.error("部门xxx不存在");
  }
  // 验证 3
  Long count = employeeDao.countByDepartmentId(departmentId);
  if (count != null && count <= 0) {
    return Result.error("员工不存在");
  }
  // 操作数据库 4
  Long departmentSort = departmentEntity.getSort();
  departmentEntity.setSort(swapEntity.getSort());
  departmentDao.updateById(departmentEntity);
  swapEntity.setSort(departmentSort);
  departmentDao.updateById(swapEntity);
  return Result.OK("success");
}

The above code is often encountered when we adopt a three-tier architecture, so what's wrong with it?

The above code is a typical long transaction problem ( similar to calling third-party interfaces ), the first three steps are to use the connection to verify the operation, but because there are @Transactional annotations on the method, these three verifications are all using the same a connection.

For complex business and complex verification logic, the entire verification process will always occupy the connection connection, which may take a long time, and the connection will not be returned to the database connection pool until the end of the method.

For the unpredictable situation of complex business, it is not a good thing to occupy the same connection for a long time, and the occupation time should be shortened as much as possible.

Explanation: For the @Transactional annotation, when spring encounters this annotation, it will automatically obtain the connection from the database connection pool, start the transaction and then bind it to ThreadLocal. If the business does not enter the final operation database link, then there is no If it is necessary to obtain a connection and start a transaction, the connection should be returned directly to the database connection pool for other use.

So we can write like this after adding the Manager layer:

DepartmentService.java
  
public Result<String> upOrDown(Long departmentId, Long swapId) {
  // 验证 1
  DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
  if (departmentEntity == null) {
    return Result.error("部门xxx不存在");
  }
  // 验证 2
  DepartmentEntity swapEntity = departmentDao.selectById(swapId);
  if (swapEntity == null) {
    return Result.error("部门xxx不存在");
  }
  // 验证 3
  Long count = employeeDao.countByDepartmentId(departmentId);
  if (count != null && count > 0) {
    return Result.error("员工不存在");
  }
  
  // 操作数据库 4
  departmentManager.upOrDown(departmentSort,swapEntity);

  return Result.OK("success");
}
DepartmentManager.java
  
@Transactional(rollbackFor = Throwable.class)
public void upOrDown(DepartmentEntity departmentEntity ,DepartmentEntity swapEntity){
  Long departmentSort = departmentEntity.getSort();
  departmentEntity.setSort(swapEntity.getSort());
  departmentDao.updateById(departmentEntity);
  swapEntity.setSort(departmentSort);
  departmentDao.updateById(swapEntity);
}

The data is prepared in the service layer, and then passed to the manager layer, and the manager layer adds @Transactionaltransaction annotations for database operations.

Guess you like

Origin blog.csdn.net/weixin_45740811/article/details/128934070