MVC层次划分简述

MVC层次划分简述


写在前面的一段话:

首先要知道MVC三层架构之间有什么关系:

  • MVC:【 Model(数据模型) - View(视图) - Controller(控制器) 】

  • 三层架构:【 Presentation tier(展现层) - Application tier(应用层)+Date tier(数据访问层) 】

很多人都有一个误解,认为Spring MVC的M、V、C对应三层架构,其实是不对的!MVC只是三层架构中的展现层,MVC中的M是数据模型,是包含数据的对象,通常我们使用Spring MVC的时候有一个包叫Model,里面放的类就是用来和V交互的,V就是视图界面,包jsp,html,freemarker,velocity,thymeleaf等,C就是控制器了(通常用@Controller注解的类)。

而整个三层架构,其实是由Spring负责全局管理的,一般Service和Dao跟应用层和数据访问层有关。
MVC层次划分简述


早期分层:[ M - V - C ]:

MVC框架强制性的把各层的实现功能划分开,各自处理各自的任务,利于解耦和,极大的增强了代码的可读性、维护性。

  • M(Model)数据模型——与数据库交互的数据模型,进行数据相关操作
  • V(View)视图——是展示给用户的最终页面。视图负责将数据以用户友好的形式展现出来,负责收集展示数据。
  • C(Controller)控制器——收到请求后,调用模型层与数据库交互获取数据,最后将数据返回给视图(用户), 负责整体的接收数据和逻辑处理处理 HTTP 请求的任何操作所必须经过的中介

1. Model的职责

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

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

2. View的职责

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

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

3. Controller的职责

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

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

当用户通过浏览器发送请求到视图层(view)时,控制层(controller)分发调用模型层(model),进行数据库查询,接下来模型层(model)再将数据库查询到的数据返回给控制层(controller),控制层(controller)再将其返回给视图层(view),view层通过web页面把数据信息显示给用户。
MVC层次划分简述

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.
在设计良好的MVC应用程序中,Controller通常非常薄,可能只包含几十行代码;而Model则非常胖,其中包含负责表示和操作数据的大多数代码。


目前市面上流行的实际分层方式[ S - D(M) - V - C ]:

以前,很多人认为可以直接在Controller层就调用model层来进行数据库的交互。但是这是不严谨的,耦合性太强,违背了MVC的初衷,即解耦。所以随着MVC学习的深入,慢慢地又加入到了业务层Service和数据访问层Dao:

  • D(Dao)数据访问对象——与数据库建立连接,封装了对数据库的CURD操作
  • S(Service)业务逻辑模型——做一些业务逻辑地处理,并给Controller返回结果
  • V(View)视图——是展示给用户的最终页面。视图负责将数据以用户友好的形式展现出来,负责收集展示数据。
  • C(Controller)控制器——接收用户传递过来的数据,将数据封装到实体类中,调用业务逻辑模型,进行业务逻辑的处理,根据业务逻辑模型返回的结果,进行不同的视图跳转。
    MVC层次划分简述
    当请求来了,controller就会将相应的请求分发到相应的service层,在service层中再调用dao层进行数据库交互。这里的dao层其实就是之前的model层,封装了对数据库的操作。这样一来,就把业务处理逻辑从controller中分离出来,从而实现了解耦。

一个典型的页面浏览行为在程序端的流程是这样的:

MVC层次划分简述

  1. 控制器最先被调用,并被赋予外部输入
  2. 控制器根据外部输入向模型请求数据
  3. 模型从数据库获取数据并发送数据到控制器
  4. 控制器处理该数据并发送封装好的数据到视图
  5. 视图根据接到的数据最终展示页面给用户浏览

使用Java进行MVC模式开发时,数据模型往往分为两部分,即DAO(Data Access Object,数据访问对象)和Service(业务逻辑模型)。在第2步中(控制器根据外部输入向模型请求数据),控制器向模型请求数据时,并不是直接向DAO请求数据,而是通过Service向DAO请求数据。这样做的好处是,可以将业务逻辑与数据库访问独立开,为将来系统更换数据保存介质(如目前系统使用文件系统存储数据,将来可以更换为使用数据库存储,又或者是现在使用了MySQL存储数据,将来更换为Oracle或是Mysql等)提供了很大的灵活性。另外,由工具层(util),实体类层(model/po/pojo)被其他层调用,为其提供服务。