Enhancing MVC Architecture with a Manager Layer in Java
The article explains the classic three‑layer MVC pattern, its shortcomings in complex Java projects, and proposes adding a Manager layer to separate generic business processing, reduce transaction scope, and improve code organization, illustrated with Spring‑based code examples.
The author introduces the widely taught MVC (Model‑View‑Controller) architecture, which separates a system into Model, View, and Controller layers. In typical Java projects this translates to three directories: controller , service , and dao , representing the presentation, business, and data‑access layers respectively.
While MVC is simple, the author points out several drawbacks as business logic grows: bloated Service code, large or nested transactions, business logic leaking into the DAO layer, and complex SQL in the DAO.
To address these issues, the article references the "Alibaba Java Development Manual" and suggests inserting a generic business‑processing layer called the Manager layer beneath the Service layer. The Manager layer provides atomic service interfaces, handles third‑party platform wrappers, offers common capabilities such as caching, and interacts with multiple DAOs.
In practice, the Service layer orchestrates calls to the Manager layer, keeping transaction boundaries clear and preventing nested transactions. The Manager layer should not call each other, and it centralises business‑related SQL, reducing complex joins and database load.
Example usage: a user‑information service calls getUser in the Service layer, which in turn interacts with the DAO. When a new requirement demands automatic user creation if the user does not exist, the Manager layer supplies a createUser method while the Service layer composes the overall workflow.
Code illustration of the original three‑layer approach shows a long‑transaction method annotated with @Transactional , performing multiple validations and database updates within a single transaction, which can hold a database connection for an extended period.
@Transactional(rollbackFor = Throwable.class)
public Result
upOrDown(Long departmentId, Long swapId) {
// validation 1
DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
if (departmentEntity == null) {
return Result.error("部门xxx不存在");
}
// validation 2
DepartmentEntity swapEntity = departmentDao.selectById(swapId);
if (swapEntity == null) {
return Result.error("部门xxx不存在");
}
// validation 3
Long count = employeeDao.countByDepartmentId(departmentId);
if (count != null && count > 0) {
return Result.error("员工不存在");
}
// database operation 4
Long departmentSort = departmentEntity.getSort();
departmentEntity.setSort(swapEntity.getSort());
departmentDao.updateById(departmentEntity);
swapEntity.setSort(departmentSort);
departmentDao.updateById(swapEntity);
return Result.OK("success");
}After introducing the Manager layer, the Service method becomes slimmer, delegating the transactional database updates to the Manager:
public Result
upOrDown(Long departmentId, Long swapId) {
// validation 1
DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
if (departmentEntity == null) {
return Result.error("部门xxx不存在");
}
// validation 2
DepartmentEntity swapEntity = departmentDao.selectById(swapId);
if (swapEntity == null) {
return Result.error("部门xxx不存在");
}
// validation 3
Long count = employeeDao.countByDepartmentId(departmentId);
if (count != null && count > 0) {
return Result.error("员工不存在");
}
// delegate to manager
departmentManager.upOrDown(departmentEntity, swapEntity);
return Result.OK("success");
}
@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);
}By moving the transactional logic to the Manager layer, the Service layer only prepares data, while the Manager handles the actual database operations within a clearly scoped transaction, reducing connection hold time and improving maintainability.
The article concludes with a call for readers to like, share, and follow the author’s public account, and promotes additional paid resources such as a knowledge‑sharing community and advanced Spring, MyBatis, and micro‑service tutorials.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.