0

0

实例讲解MVC架构的含义及职责划分

藏色散人

藏色散人

发布时间:2022-01-07 14:09:40

|

7585人浏览过

|

来源于awaimai

转载

最近负责一个项目,用了 yii framework 的 mvc 框架,刚开始自以为结构很稳健。

但是随着对业务逻辑理解的深入,才开始意识到问题的严重。

我错误地理解了 MVC 中的 Controller,想当然地根据以往的经验,把所有的业务逻辑都放在 Controlleraction 中去实现。

于是,每一个 Controller代码都上千行,越来越臃肿

最后,我下定决心重构代码,起源是一个对外开放 API 接口的需求。

按照现在的架构,代码基本无法复用,我需要把很多功能再重复写一遍,这实在是无法接受。

面向对象编程不仅仅是课本上的名词啊!

真正开始实践才发现,要有面向对象意识,有全局观,是多么难得的一件事情。

88d7a167e8b2a083842b5929eb92afe.png

1 到底什么是 MVC

模型-视图-控制器(MVC)是一种设计框架(设计模式)

MVC 的目标将业务逻辑从用户界面的考虑中分离

这样,开发者就可以更容易地改变每一部分而不会影响其他。

在 MVC 中,

  • Model 代表数据和业务规则
  • View 包含了用户界面元素,例如文本,表单等;
  • Controller 则管理模型和视图中的通信

MVC 在各种编程语言中均有实现,例如 J2EE 应用开发中,

View 可能由 jsp 实现;Controller 是一个 servlet,现在一般用 Struts 实现;Model 则是由一个实体 Bean 来实现。

2 我遇到了什么问题

Yii Framework 是一个流行的 PHP 框架,它借鉴了 Ruby on Rails 的 ActiveRecord(AR) 概念。

数据库中的每一个 table 都可以用 AR 类来方便地进行增删改查操作。

它把 AR 当做 Model,并推荐放在一个名为 models 的目录下面。

于是,我在自动生成表对应的 AR 之后,便望文生义想当然地认为已经拥有了 Model 层。

其实,AR只不过是 DAO (数据访问层),并不是 Model 层

我们的业务几乎全放在了 Controller 里:对用户提交上来的表单进行各种逻辑判断,进行计算,实例化 AR 对数据进行存储……

因为一个 Controller 中会有多个 action,每个 action 都有这样的业务处理。

最后,我发现我的 Controller 代码已经超过了 1000 行。

突然有一天,leader 说,我们这个系统要开放 API 给现有的旧系统调用,要给第三方接口。

第三方只是要给定一个参数,本系统给出个结果值而已,这其中的业务处理它是不关心的。

坏就坏在这里,Controller 已经实现了那些业务,但它是接受表单提交的,怎样能够也接受 SOAP 的 xml 文档呢?

Controller 和套套一样,应该越薄越好。

它的职责应该只是接受用户的输入,然后立刻转发给别的类来处理

这样 Controller 只负责提供不同的接口,我们才能算是将业务逻辑分离出去,而分离出去的业务也很容易进行重用。

分离出来的这部分业务由谁来处理呢?答案应该是 Model

3 View的职责

View部分比较明确,就是负责显示。

一切与显示界面无关的东西,都不应该出现在view里面。

燕雀Logo
燕雀Logo

为用户提供LOGO免费设计在线生成服务

下载

因此,View 中一般不应该出现复杂的判断语句,以及复杂的运算过程。

可以有简单的循环语句、格式化语句。比如,博客首页的文字列表就是一种循环。

对于PHP的Web应用而言,HTML是View中的主要内容

View应该从不调用Model的写方法

也就是说,View只从Model中读取数据,但不改写Model。

所以我们说,View和Model是老死不相往来的。

而且,View中不直接访问$_GET$_POST,应该由Controller传递给View。

此外,View一般没有任何准备数据处理的内容,如查询数据库等。

这些一般是放在Controller里面,并以变量的形式传给视图。

也就是说,视图里面要用到的数据,就是一个变量

4 Model的职责

对于Model而言,最主要就是保存和输出信息

比如,Post类必然有一个用于保存博客文章标题的title属性,必然有一个删除的操作,这都是Model的内容。

数据、行为、方法是Model的主要内容

实际工作中,Model是MVC中代码量最大

Model是逻辑最复杂的地方,因为应用的业务逻辑也要在这里表示。

注意将Model与Controller区分开。

Model是处理业务方面的逻辑,Controller只是简单的协调Model和View之间的关系。

只要是与业务有关的,就该放在Model里面。

数据校验、public常量和变量,都应该放在model层,

也就是说,有可能被重复使用的属性或方法,都应该放在model层,一次定义,到处使用。

Model不应该访问request、session以及其他环境数据,这些应该由Controller注入。

好的设计,应该是胖Model,瘦Controller

5 Controller的职责

对于Controller,主要是响应用户请求,决定使用什么视图,需要准备什么数据用来显示

因此,对于request的访问代码,应该放在Controller里面,比如$_GET$_POST等。

Controller应该仅限于获取用户请求数据,不应该对数据有任何操作或预处理,这应该放在 Model 里面。

对于数据的写操作,要调用Model类的方法完成。

对于用户请求的响应,要调用视图渲染。

此外,一般不要有HTML代码等其他表现层的东西,这应该是属于View的内容。

6 启示

Yii Framework 的官方文档中有这么一段:

In a well-designed MVC application, controllers are often very thin, containing probably only a few dozen lines of code; while models are very fat, containing most of the code responsible for representing and manipulating the data.

简言之,Rich Model is Better

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
struts框架介绍
struts框架介绍

本专题介绍了struts框架相关内容,阅读专题下面的文章了解更多详细内容。

76

2025.08.06

servlet生命周期
servlet生命周期

Servlet生命周期是指Servlet从创建到销毁的整个过程。本专题为大家提供servlet生命周期的各类文章,大家可以免费体验。

375

2023.08.08

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1500

2023.10.24

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

94

2023.09.25

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

56

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

52

2025.11.27

session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

315

2023.10.17

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

748

2023.10.18

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 8万人学习

Django 教程
Django 教程

共28课时 | 3.6万人学习

React 教程
React 教程

共58课时 | 4.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号