MVC演化史

标签: Technical MVC MVP | 发表时间:2011-05-02 21:49 | 作者:老王 huige
出处:http://huoding.com

Martin Fowler在他所写的《企业应用架构模式》一书中感慨道:MVC已经成为我们最常误用的模式。人们之所以常常误用MVC,很大程度上是因为混淆了不同的MVC变体。

Classic MVC

大概上世纪七十年代,Xerox PARC的Trygve提出了MVC的概念,并应用在Smalltalk系统中,为了和其它类型的MVC加以区分,历史上习惯的称之为Classic MVC。

  • Model:封装领域数据及逻辑
  • View:查询领域数据并展现给用户
  • Conctroller:截获用户请求并改变领域数据

注意:从依赖关系看,Model不依赖View和Controller,而View和Controller依赖Model。

Classic MVC关注两个分离:

  • 从Model中分离View
  • 从View中分离Controller

从Model中分离View,主要基于以下几点考虑:

  • 不同的关注点:Model关注内在的不可视的逻辑,而View关注外在的可视的逻辑。
  • 多种表现形式:同一个Model往往需要多种View表现形式,如文本、图像。
  • 提高可测试性:相对Model而言,View是不容易测试的。

从View中分离Controller就不那么重要了。Desktop软件的时代,View和Controller往往是一一对应的关系,所以常常把他们合并成为UI,事实上,当时多数UI框架都没有实现从View中分离Controller。后来随着Web的兴起,这种分离(模板技术)才开始流行起来。

本质上Classic MVC的结构如下图所示,之所以说本质上,是因为View和Controller其实是彼此关联的,但这种关联和稍后提到的MVP完全不同,更像是一种框架的副产品,为了避免引起混淆,这里省略了它们,具体参阅:How to use Model-View-Controller (MVC)

Classic MVC

Classic MVC

图解:Controller截获用户通过鼠标或键盘发出的请求,然后改变Model的状态,Model通过Observer Synchronization通知View自己的状态发生了变化,View查询Model展现数据。

Classic MVC并不完美,不适用于复杂的逻辑。举个例子:用户通过鼠标拖动滚动条来调整音量大小,如果音量大于某个数值,背景色变红以示提醒。当使用Classic MVC的时候,如何处理背景色变红的逻辑呢?有两个选择:

  • Model触发一个特殊事件,View收到后完成相关逻辑的处理。但我们前面说过,从依赖关系上看,Model应该完全无视View的存在,所以这样的味道很坏。
  • 在View中判断音量临界值,达到后完成相关逻辑的处理。但我们前面说过,View是不容易测试的,应该尽可能减少逻辑处理,所以这样的味道同样不好。

Application Model MVC

大概上世纪八十年代,ParcPlace从Xerox Parc划分出来,负责Smalltalk的研发工作,为了适应更复杂的逻辑,开发了Classic MVC的改进版,也就是Application Model MVC,在原有架构基础上引入了Application Model,如下图所示:

Application Model MVC

Application Model MVC

图解:Application Model在Model和View、Controller之间扮演着一个中继者的角色。

接着看前面的例子,既然Model和View都不适合放背景色变红的逻辑,那么我们可以尝试把相关逻辑放在Application Model中实现,当用户通过鼠标调整音量大小时,Model触发一个普通事件,Application Model拦截到这个事件,判断音量是否大于临界值,如果是就触发一个特殊事件,View收到后完成相关逻辑的处理。

Application Model MVC虽然看似解决了复杂逻辑的问题,但它仍然存在硬伤:

首先随着以微软视窗为主的图形化操作系统的兴起,操作系统本身提供了一套原生的View接口,用来截获用户通过鼠标或键盘发出的请求,结果让Controller显得多余了。

其次由于在Application Model MVC中,View的渲染只能通过事件的方式实现,Application Model不能直接操作View,所以某些情况下不能方便的实现业务逻辑。接着前面说的调节音量的例子,这次我们加个新功能,不再通过鼠标拖动滚动条来调整音量大小,而是给出一个文本框,让用户直接通过键盘输入阿拉伯数字表示音量大小,一旦用户输入非法内容(比如说英文字符),背景色变黄以示警告。问题是如果用户输入非法内容,就不应该改变Model的状态,但不改变Model的状态,View就没有机会收到渲染的事件。

MVP

大概上世纪九十年代,IBM的Mike Potel提出了MVP的概念。与此同时,Smalltalk团队正在开发新一代框架,当他们看到MVP时,发现它不仅和MVC非常相似,并且很好的解决了复杂逻辑的问题,所以决定使用它,出于复杂度的关系,他们简化了MVP,最终看上去更像是把原本的MVC扭转了一个角度,把其中的VC颠倒了一下顺序:

MVP

MVP

图解:View截获用户请求,然后委派给Presenter,Presenter改变Model的状态,Model通过Observer Synchronization通知View自己的状态发生了变化,View查询Model展现数据。

最重要的是一点是Presenter和View彼此持有对方的引用。虽然View截获用户请求,但它并不处理,而是委派给Presenter处理,保证了可测试性,同时,因为Presenter可以直接操作View,不必受限于观察者模式。

接着前面说的调节音量的例子,当用户通过鼠标拖动滚动条来调整音量大小时,View截获请求,并把请求委派给Presenter,如果Presenter发现音量大于临界值,直接操作View实现逻辑;当用户通过键盘输入音量大小时,View截获请求,并把请求委派给Presenter,如果Presenter发现内容非法,直接操作View实现逻辑。

Martin Fowler分析了MVP的实现方式,分类为Supervising ControllerPassive View

Supervising Controller and Passive View

Supervising Controller and Passive View

图解:MVP的两种分类:Supervising Controller和Passive View

二者的区别在于Model和View是否有联系,在Supervising Controller的实现中,View可以查询Model,Model状态发生变化的话会通知View,而在Passive View的实现中,View不可以查询Model,Model状态发生变化的话会通知Presenter,由Presenter完成View的渲染。比较而言,Passive View的可测试性更好一些,但Presenter的代码量相应大些。

前面我们讨论了MVC到MVP的演化史,随着Web的兴起,人们开始把MVC,MVP等知识应用到Web环境下,但Web环境有其特殊性,最重要的一点就是HTTP是无状态的,每次请求都是独立的,所以不可能实现观察者模式。

Web MVC

Java是Web MVC最早的实践者,开发出Model 2,使用JavaBean,JSP,Servlet分别对应MVC中的三个组成部分,紧接着Structs的出现开始让大众注意到Web MVC,不过真正让Web MVC流行起来的却是Ruby社区的Rails,其大致流程如下图所示:

Web MVC

Web MVC

图解:一个典型的Web MVC流程

  1. Controller截获用户发出的请求
  2. Controller调用Model完成状态的读写操作
  3. Controller把数据传递给View
  4. View渲染最终结果并呈献给用户

在Classic MVC中,Controler可以改变Model的状态,View可以查询Model的状态,所以说对Model而言,Controller和View的地位是平等的,不过在Web MVC中,Controller变成了中继者,主要工作是协调Model和View,如此看来,Web MVC中的Controller等同于MVP中的Presenter。那为什么不叫Web MVP,而称之为Web MVC?这是因为截获请求的是Controller而不是View。

花絮:Python社区的Django框架宣称自己使用的是MTV,其实质仍然是Web MVC。

Web MVP

在Desktop的时代,微软通过WinForms实现MVP,把组件化编程发挥到了极致,大大提升了开发效率,随着Web的兴起,微软希望延续这样的编程模式,所以使用WebForms实现了Web MVP,引入了CodeBehind,ViewState等设计概念。WebForms的优点和缺点都很突出,篇幅所限,具体的描述大家可以参考下面链接:

  1. 为WebForms说几句话,以及一些ASP.NET开发上的经验(1)
  2. 为WebForms说几句话,以及一些ASP.NET开发上的经验(2)
  3. 为WebForms说几句话,以及一些ASP.NET开发上的经验(3)

注:微软推出了ASP.NET MVC向Web MVC靠拢,似乎要两手抓两手都要硬。

ASP.Net MVP vs MVC

ASP.Net MVP vs MVC

图解:微软Web MVP vs Web MVC。注意截获请求的是Controller还是View!

以上便是MVC的演化史,我尽量让描述浅显易懂,但文字总是枯燥的,还好有好事者做了一首MVC之歌:Model-View-Controller Song,闲暇无事之时不妨听听。

最后以C2上的一句话结尾:We need SMART Models, THIN Controllers, and DUMB Views

说明:本文使用了下列链接中的内容:

相关 [mvc 演化] 推荐:

MVC演化史

- huige - 火丁笔记
Martin Fowler在他所写的《企业应用架构模式》一书中感慨道:MVC已经成为我们最常误用的模式. 人们之所以常常误用MVC,很大程度上是因为混淆了不同的MVC变体. 大概上世纪七十年代,Xerox PARC的Trygve提出了MVC的概念,并应用在Smalltalk系统中,为了和其它类型的MVC加以区分,历史上习惯的称之为Classic MVC.

Spring MVC 和 Struts2

- - CSDN博客架构设计推荐文章
Web层面的框架学习了三个Struts1和2,SpringMVC,那他们之间肯定存在一个优劣和适用的环境,Struts1和2的异同点我已经做过对比《 Struts1和Struts2》,这篇将对比下Struts2和SpringMVC的异同,下面数据基本来源于网络,本人是搜集整理所得,供大家参考. 一个项目使用什么样的技术,决定的因素很多,我所能想到的有:对系统的性能、开发的效率、团队学习的成本、业务场景等,下面尽量从这几个方面入手,来分析比较下他们之间存在的优劣.

最佳MVC实践

- - CSDN博客架构设计推荐文章
原文地址 http://www.yiiframework.com/doc/guide/1.1/zh_cn/basics.best-practices 最佳MVC实践(Best MVC Practices). Although Model-View-Controller (MVC) is known by nearly every Web developer, how to properly use MVC in real application development still eludes many people.

srping mvc RequestMapping实现

- - CSDN博客推荐文章
spring mvc中定义请求的url只需要在方法上添加注解: @RequestMapping("aa.mvc")即可定义访问的url地址,但是你是否有考虑过为什么添加这个注解就可以实现url访问地址的定义了呢. 首先定义注解RequestMapping. mvc中常需要对输入值进行合法性校验,所以也定义了校验的注解MyValid.

MVC就是个选择题

- Dash - Becomin' Charles
由于采用了Web开发框架来开发项目,所以我首次在真正的项目中采用MVC的开发模式. 随着项目的不断深入,我也在不断反思,MVC设计模式到底给项目带来了什么. 听起来都很难听对吗,但是确实如此. 清晰的代码结构,易于维护,易于扩展. 当然,我不是在批判MVC,只是觉得,在使用MVC过程中,还是需要投入更深入的思考,到底怎样才能用好这个设计模式.

表现层模式-MVC

- - 博客园_首页
       在前面简述了从服务层到数据层参见 架构设计目录. 剩下了表现层,一个再好的中间层表现也必须有一个用户界面,提供和用户交互,将用户行为输入转化为系统操作,进入后台逻辑. 在当下RAD(快速应用开发)工具的支持下,我们可以比较快速的完成UI设计,RAD追求所见即所得的快速反馈,快速应用.

三层架构与MVC

- - CSDN博客推荐文章
MVC是Model View Controller , 是模型-视图-控制器的缩写,一种软件设计典范.用于组织代码用 一种业务逻辑和数据显示分离的方法,这个方法的假设挑剔是如果业务逻辑被聚集到一个部件里面,而且界面和用户围绕数据的交互能被改进和个性化指定而不需要重新编写业务逻辑.. 三层架构是最基本的项目分层结果,而MVC则是三层架构的一个变体,MVC是一种好的开发模式.

Spring MVC 3 深入总结

- - 企业架构 - ITeye博客
大家好,Spring3 MVC是非常优秀的MVC框架,由其是在3.0版本发布后,现在有越来越多的团队选择了Spring3 MVC了. Spring3 MVC结构简单,应了那句话简单就是美,而且他强大不失灵活,性能也很优秀. 官方的下载网址是: http://www.springsource.org/download   (本文使用是的Spring 3.0.5版本).

Spring MVC 与 web开发

- - 码蜂笔记
项目组用了 Spring MVC 进行开发,觉得对里面的使用方式不是很满意,就想,如果是我来搭建开发环境,我会怎么做. 下面就是我的想法,只关注于 MVC 的 View 层. 现在基本上都是用 ajax 来调用后台接口,拿到 json格式的数据再展示,有的人直接返回数据,却没有考虑异常的情况,我觉得返回的报文里必须包含表示可能的异常信息的数据和业务响应数据.

Spring MVC的常见错误

- - Java译站
10年前我开始自己的职业生涯的时候,Struts还是市场上的主流标准. 然而多年过后,我发现Spring MVC已经越来越流行了. 对我而言这并不意外,因为它能和Spring容器无缝集成,同时它还提供了灵活性及扩展性. 从我迄今为止对Spring的经验来看,我发现有不少人在配置Spring的时候经常会犯一些常见的错误.