MVC架构
定义
MVC是一种软件架构模式,常用于图形化界面和 Web 应用的设计,全称是:
- M:Model(模型)
- V:View(视图)
- C:Controller(控制器)
它的核心思想就是:MVC通过职责分离和分层控制,把数据、显示、逻辑分开,让代码更清晰、好维护,是现代Web开发(如Spring MVC、ASP.NET MVC)的基石
组成部分
Model
负责存储、处理、管理数据(如数据库里的表、业务逻辑里的计算、数据库增删改查等等)
它不管怎么显示,只管数据正确不正确
包含内容:
- POJO/Bean/Domain:数据实体类,描述业务对象
- Service:实现核心业务逻辑(如用户注册、订单处理)
- Dao(Data Access Object数据库访问对象):负责数据持久化操作(如数据库增删改查)
View
专门负责显示给用户看的内容(如网页界面、APP 界面、桌面程序的窗口)
它只关心怎么展示,而不关心数据是怎么来的
Controller
负责接收用户输入和请求(如点按钮、提交表单),然后告诉 Model 去处理数据,再把结果交给 View 来展示
举个用户注册的栗子:
用户请求:通过View(如HTML表单)提交注册信息
Controller接收:解析请求参数,调用Model层的UserService处理注册逻辑
Model处理:
UserService校验数据,调用UserDao将数据存入数据库
返回处理结果(成功/失败)给Controller
Controller响应:根据结果选择View(如跳转到成功页或错误页)
View渲染:展示最终页面给用户
MVC架构和三层架构的关系
三层架构
三层架构作为一种分层架构模式,它将整个应用划分为三个清晰的层次
- 表现层(Presentation Layer):直接与用户进行交互,例如各类 UI 界面(用户和软件/设备之间交互的界面)
- 业务逻辑层(Business Logic Layer):专注于处理核心业务规则
- 数据访问层(Data Access Layer):负责与数据库或外部数据源进行交互
主要区别
对比维度 | MVC 架构模式 | 三层架构 |
---|---|---|
设计目标 | 对用户界面的交互逻辑进行解耦 | 实现整个系统的分层解耦 |
适用范围 | 主要适用于用户界面相关场景 | 适用于整个应用程序 |
层次划分 | 包含 Model、View、Controller 三个角色 | 有表现层、业务逻辑层、数据访问层三个物理层 |
典型应用场景 | 常用于 Web 框架(如 Spring MVC、ASP.NET MVC) | 适用于企业级应用的整体架构设计 |
联系互补
- MVC 可作为三层架构表现层的实现方式:在三层架构的表现层中,可以运用 MVC 模式来进一步分解 UI 逻辑。例如,Controller 负责处理请求,View 负责渲染页面,而 Model 则对应业务逻辑层的接口。
- 三层架构的业务逻辑层和数据访问层可与 MVC 协同工作:MVC 中的 Model 并非必须完全独立,它可以调用三层架构中业务逻辑层的服务,而业务逻辑层又能调用数据访问层来获取数据。
- 共同达成高内聚、低耦合的目标:两者都借助分层或角色分离的方式,提升了代码的可维护性和可扩展性。
实际应用
在一个典型的web应用里:
- 表现层:采用 MVC 模式,其中 Controller 接收请求,View 负责渲染 HTML 页面,Model 调用业务逻辑层的接口。可以说我们学习的MVC模式对应的是三层架构的表现层
- 业务逻辑层:独立存在,处理诸如订单计算、权限验证等核心业务。
- 数据访问层:负责与数据库交互,执行数据的增删改查操作。
面试高频问题
Q1:MVC 和三层架构的区别是什么?
A:MVC 是一种设计模式,强调的是 用户交互流程;而三层架构是从 系统架构角度 划分的层次结构,两者结合后形成完整的 Web 应用结构。
Q2:为什么要在项目中使用 MVC?
A:为了实现 前后端分离、逻辑清晰、易于维护、提高开发效率。各层分工明确,便于多人协作开发。
Q3:Servlet (Server Applet,Java写的服务端小程序,用来处理浏览器和服务器之间的通信)在 MVC 中属于哪一层?JSP (Java Server Pages,是运行在服务器端的动态网页技术)呢?
A:
- Servlet 属于 Controller 层,用于接收请求和控制流程;
- JSP 属于 View 层,用于展示数据和页面渲染。
Q4:如果不用 MVC,会有什么问题?
A:会出现大量业务逻辑混杂在 JSP 页面中,导致代码难以维护、不易测试、安全性差等问题。
Q5:如何保证各层之间的低耦合(使各模块互不影响)?
A:通过接口编程、依赖注入等方式,使各层之间仅依赖接口而非具体实现类。
参考: