MVC架构的职责划分原则

来源:互联网 发布:ubuntu怎么用qq 编辑:程序博客网 时间:2024/06/06 02:47

最近负责一个项目,用了 Yii Framework 的 MVC 框架,刚开始自以为结构很稳健。但是随着对业务逻辑理解的深入,我开始意识到问题的严重,我错误地理解了 MVC 中的 Controller,想当然地根据以往的经验,把所有的业务逻辑都放在 Controller 的 action 中去实现,于是,每一个 Controller 的代码都上千行,越来越臃肿。

最终导致我下定决心对这两个月工作进行重构的,是一个对外开放 API 接口的需求。按照现在的架构,代码基本无法复用,我需要把很多功能再重复写一遍,这实在是无法接受的。面向对象编程不仅仅是课本上的名词啊!真正开始实践才发现要有面向对象意识,有全局观,是多么难得的一件事情。

MVC设计原则

一、到底什么是 MVC?

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

MVC 的目标是将业务逻辑从用户界面的考虑中分离,这样开发者就可以更容易地改变每一部分而不会影响其他。在 MVC 中,Model 代表信息(数据)和业务规则;View 包含了用户界面元素,例如文本,表单等;Controller 则管理模型和视图中的通信。

MVC 在各种编程语言中均有实现,例如 J2EE 应用开发中,View 可能由 jsp 实现;Controller 是一个 servlet,现在一般用 Struts 实现;Model 则是由一个实体 Bean 来实现。

二、我遇到了什么问题?

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。

三、遵循的原则

对于MVC中三者的划分并没有十分明晰的定义和界线,只是一种指导思想,让你按照model,view,controller三个方面来描述你的应用,并通过这三者的的交互,使应用功能得以正常运转

3.1 View的职责

其中,View部分比较明确,就是负责显示。一切与显示界面无关的东西,都不应该出现在view里面。因此,view中一般不会出现复杂的判断语句,不会出现复杂的运算过程。对于PHP的Web应用而言,毫无疑问,html是view中的主要内容。如下是关于view的几个原则:

  1. 负责显示界面,以HTML为主
  2. 一般没有复杂的判断语句或运算过程,可以有简单的循环语句、格式化语句。比如,博客首页的文字列表就是一种循环;
  3. 从不调用Model的写方法。也就是说,View只从Model中获取数据,而从不改写Model,所以我们说他们是老死不相往来的。
  4. 一般没有任何准备数据处理的内容,如查询数据库等。这些一般是放在Controller里面,并以变量的形式传给视图。也就是说,视图里面要用到的数据,就是一个变量

3.2 Model的职责

对于Model而言,最主要就是保存事物的信息,保证事物的行为和对他可以进行操作。比如,Post类必然有一个用于保存博客文章标题的title属性,必然有一个删除的操作,这都是Model的内容。以下是关于Model的几个原则:

  1. 数据、行为、方法是Model的主要内容;
  2. 实际工作中,Model是MVC中代码量最大,逻辑最复杂的地方,因为关于应用的业务逻辑也要在这里表示;
  3. 注意与Controller区分开。Model是处理业务方面的逻辑,Controller只是简单的协调Model和View之间的关系。只要是与业务有关的,就该放在Model里面。好的设计,应该是胖Model,瘦Controller;

3.3 Controller的职责

对于Controller,主要是响应用户请求,决定使用什么视图,需要准备什么数据用来显示。以下是有关Controller的设计原则:

  1. 用于处理用户请求,因此,对于request的访问代码应该放在Controller里面,比如$_GET$_POST等。但仅限于获取用户请求数据,不应该对数据有任何操作或预处理,这应该放在model里面。
  2. 调用model类的方法,对model进行写操作。
  3. 调用视图渲染函数,形成对用户request的response。
  4. 一般不要有html代码等其他表现层的东西,这应该是属于view的内容。

四、得到的启示

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

0 0
原创粉丝点击