MVC架构------模型、视图、控制
MVC代表Model-View-Controller(模型-视图-控制器)三个组件的缩写,旨在通过分层设计实现代码解耦,以提升代码的可维护性和复用性。
三个模块的功能分别为:
- 控制器 Controller :负责接收用户请求,转发到对应的处理模块,调用业务层
Service并把结果返回给视图View,不可直接调用Dao; - 模型 Model :负责处理具体的业务逻辑,包括与数据库的交互,该层在项目结构中的体现为
Service业务层,通常聚合Dao持久层; - 视图 View :只负责展示数据,不包含任何业务逻辑,项目中通常为
html、ftl等标记语言。
整体流程如下图:

教科书中的经典 MVC 架构 认为,模型Model层 应该只包含POJO等用于封装数据的实体类,仅作为数据载体,不承担业务逻辑与数据访问操作;而Service业务层 和 Dao持久层,属于 Spring 项目独有的后端分层架构,不属于经典 MVC 定义。
笔者认为,实际企业级 Spring 项目下的 MVC 架构应理解为:
- Controller 用于接收并转发用户请求,聚合Service实例以调用业务逻辑;
- Service 负责完成具体逻辑,结合持久层,通常聚合Dao
- Dao 负责完成与数据库的交互,方法上注解添加具体sql语句
- Pojo 接收中间结果的实体类,简化传递类型
- html等前端页面,负责接收并展示数据,同时将用户请求转发到Controller控制层
项目结构通常为:
- 控制层 Controller:请求处理包
Controller; - 模型层 Model:实例对象
Pojo、业务包Service和持久层包Dao; - 视图层 View:前端展示页面
html、ftl等。
简单示例代码如下:
- 控制层
Controller.java
java
public class IndexController {
@Autowired
private Service service;
@GetMapping("/index")
public String index() {
// 后续完善页面内容
return service.findUser().toString();
}
}
- 实例对象
Pojo.java
java
public class User {
private int id;
private String username;
private String password;
// 省略get set方法
}
- 业务处理
Service.java
java
@Component
public class Service {
@Autowired
private UserDao userDao;
public List<User> findUser() {
List<User> users=userDao.findAll();
return users;
}
}
- 持久层
Dao.java
java
public interface UserDao {
@Select("select * from userinfo")
@Results({
// 主键映射
@Result(column = "id",property = "uid",id = true),
@Result(column = "name",property = "name")
})
List<User> findAll();
}
- 视图页面
index.ftl
html
<html>
<head>
<meta charset="UTF-8">
<title>Freemarker</title>
</head>
<body>
Hello!
<#list users as user>
${user}
</#list>
</body>
</html>
DDD架构------领域驱动设计,Domain-driven Design
MVC架构把所有数据逻辑都堆在Service层,会带来三大问题:
- Service 层过度膨胀:所有业务判断、流程、规则全部堆积在此,形成臃肿混乱的 "大泥球代码"。
- 出现贫血模型:POJO 实体仅作为纯数据载体,只有字段 + Getter/Setter,无任何业务行为;核心逻辑四散在 Service 中,内聚性极差。
- 系统复杂度失控:随着业务迭代,业务规则散落在 Controller、Service、DAO 各处,语义混乱、链路不清,后期维护与迭代成本极高。
在这样的背景下,Eric Evans 在 2003 年提出了Domain-Driven Design(领域驱动设计),其核心思想是:
软件设计应该围绕业务领域进行建模,而不是围绕数据库、CURD等技术实现。
DDD的两大核心是领域模型和限界上下文:
- 领域模型 :某个边界内,对业务核心概念、规则、行为的抽象表达,通常包含实体、聚合根、服务和事件; 实体包含行为方法,即具体的业务逻辑;
聚合根是相关实体的集合,如
Order是聚合根,内部管理多个OrderItem订单项领域服务是跨实体或聚合根的处理逻辑,只包含业务逻辑
领域事件是用于触发后续业务逻辑,标记业务状态转变的方法,可保持上下文之间解耦
- 限界上下文 :一个词在不同业务内应表达不同含义,即每个领域内都有单独的实体 如在订单上下文中
User=联系人、收货地址、电话身份认证上下文中
User=账号、密码、手机号会员上下文中
User = 积分、成长值、会员等级
DDD将领域内模型划分为如下四层(上层还有具体的业务领域,如auth(认证)、order(订单)、member(会员)):
- 用户接口层(User Interface):处理用户请求,返回响应(对应
Controller)。 - 应用层(Application):协调领域对象完成业务用例,不包含业务逻辑(只调用方法的
Service)。 - 领域层(Domain):包含核心业务规则与模型,是系统核心(处理逻辑的
Pojo)。 - 基础设施层(Infrastructure):提供技术能力(如数据库、消息队列)。
补充:
其实这设计有点微服务的思想:
微服务是把程序拆分成多个可独立运行的服务;
DDD则是关注业务逻辑,把一个高内聚的业务写在一起,避免功能分散;
二者主要是抽象层次不同,DDD关注软件的逻辑结构,而微服务架构则更侧重于系统整体的架构布局
总结
MVC架构关注请求、数据和视图分离,但因为通常使用贫血模型 ,业务逻辑都写在Service层内,实体类Pojo中只有基础属性和get、set方法,导致业务逻辑复杂难以维护。
DDD则提倡充血领域实体收拢业务规则 ,设计中只关注业务,而非拘泥于实现方式,使用类似"微服务"的理念,每个业务领域内代码内聚,核心区别是业务逻辑从Service搬到了实体类内。
目前很多设计者可能会因为初期项目简单而选择MVC架构,但随着后续不断迭代发展,项目变得难以维护,而重构为DDD架构的成本又很高,所以除了一锤子买卖,只要需要长期维护的项目都应使用DDD架构。