设为首页收藏本站

新微赢技术网

 找回密码
 注册
搜索
热搜: 回贴
查看: 10629|回复: 3
打印 上一主题 下一主题

MVC的迷失?

[复制链接]
跳转到指定楼层
1#
发表于 2009-11-29 00:20:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
作者:老王

补充:传统的MVC概念是应用在桌面软件之上的,V可以查询M,C可以改变M。一条判断MVC的很重要的原则是View是否能动态的感知Model的变化,这在桌面软件上是很简单的,只要使用观测者模式就很容易办到,但是到了Web环境下,因为HTTP是无状态的,我们无法让View去观察Model,所以传统的MVC概念在Web环境下必须做出调整,这里最著名的改进方案就算是Sun公司针对Java做的Model2方案了,在Model2中,V并不直接和Mode打交道。一切和Model的交互都由Controller处理,然后Controller会把需要的Model数据放到一个View能找到的地方,并选择一个View去渲染结果。

基于这些认知,本文的部分观点或许是错误的,但我不打算删除这篇文章,就留下来让大家继续讨论吧。

MVC并不是一成不变的概念,可以参考Passive View,Supervising Controller。

================================

MVC似乎早已成为一个让人感觉审美疲劳的名词了。仅PHP社区里,各种各样宣称支持MVC的框架少说也有几十种,不过问题也很多。

首先一个问题是VIew是否有查询Model的权力?

在目前大多数MVC框架实现中,不管是修改Model状态的操作,还是查询Model状态的操作,所有和Model相关的操作都是在Controller中进行的。VIew里如果需要Model数据,一般也是先在Controller里完成对Model的操作,然后把需要的数据set到View里,从程序员的角度看,Controller在MVC中是一个中间人的角色。但我觉得这是错误的。因为在这样的MVC实现里,作为中间人存在的Controller过于万能,而VIew则显得有些残疾。在我看来,MVC中,针对M的操作,V和C是平等的。唯一的区别在于当请求达到Controller的时候,如果是修改Model状态的操作,会在Controller中进行,然后根据结果再转发给合适的View,如果仅仅是查询Model状态的操作,则Controller只是简单的把请求转发给合适的View,由View去查询Model的状态。之所以要进行这样的区分是因为不同的View对Model查询的需求也是不尽相同的,比如说一个列表页在IE浏览器里每页要显示100条,而在Ipnone手机里每页只能显示10条,这样的情况下,如果Model的查询是通过Controller进行的,那么我们的Controller是查100条还是10条呢?你可能想为每个需求都单独做一个Controller的Action方法,但那会产生若干一次性的方法,无疑是丑陋的解决方案,亦或许是进行某些if/else的判断,同样是自取其辱。所以我们说,应该在View里查询Model,而不是Controller。

再一个问题是Controller处于表现层还是应用层?

关于分层,一般都倾向于表现层,应用层,领域层,持久层的划分方式,从上至下单向依赖,在PoEAA这样圣经级别的著作中,Controller一般是作为表现层模式来介绍的,但实际上很多时候Controller是一个应用层模式。先来看一个例子,用户注册的时候,如果表单提交成功,会向用户的电子邮件里发一封欢迎信。在这个例子里,我们的Controller会先调用Model的相关方法完成用户的注册,然后可以使用PhpMailer之类的东西发送相关的电子邮件。假设Controller处于表现层,那么如果我们加入一个新的表现层,则无疑要重新实现一套Controller,这里就必然会导致重复实现发送电子邮件的逻辑。换句话说,我们的Controller里时常掺杂着一些应用逻辑。所以此时的Controller实际是处于应用层的,而且,Controller中Action的划定通常是根据用例来实施的,它本身勾画了用例的自然轮廓,进而从一个侧面说明了Controller和应用层的联系。

还有一个问题是Controller是否有权利redirect?

很多MVC框架的Controller都有一个和redirect相关的方法,用以实现从一个Action跳转到另一个Action的功能。但我要说明的是,这本质上是错误的,因为跳转是一个View关注的行为,而不是Controller。前面我们已经说过了,Controller属于应用层,而非表现层,一旦你在Controller里实现redirect操作,就会把表现层固化到Html界面之上,设想如果你要给你的应用实现一套命令行界面怎么办?在命令行里可是没有跳转一说的。或者你要用Delphi实现一个客户端软件,通过SOAP调用你的Controller程序,同样,Delphi客户端软件也不知道如何解析跳转。所以说Controller里不要使用redirect。

===============================

通过讨论,可以看到,焦点主要是集中在V和C上面,这并不奇怪,因为MVC本身就未涉及M的实现,归根到底,目前的MVC框架犯的主要错误就是没有清晰的切分V和C的职责,所以说他们不是正确的“M_V_C”,更像是一个“M_VC”。
2#
发表于 2009-12-2 07:05:04 | 只看该作者
(*^__^*) 指点系词……激扬文字……
回复 支持 反对

使用道具 举报

3#
发表于 2010-3-16 19:05:03 | 只看该作者
我回不回呢 考虑再三 还是不回了吧 ^_^
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

申请友链|小黑屋|最新主题|手机版|新微赢技术网 ( 苏ICP备08020429号 )  

GMT+8, 2024-11-18 17:19 , Processed in 0.193079 second(s), 9 queries , Gzip On, Memcache On.

Powered by xuexi

© 2001-2013 HaiAn.Com.Cn Inc. 寰耽

快速回复 返回顶部 返回列表