MVC模式已死

MVC模式:Model模型 View试图 Control控制器,是目前主流模式,被当作服务器软件入门基本模式学习和掌握,主流框架Struts 1/2 JSF Wicket基本都顺理成章支持MVC模式。

但是,随着时间推移,MVC模式也暴露出大量缺点,因为MVC模式本质上是一个结构型模式,结构模式相比行为模式而言,实际就是静止的,相对固定的,而随着B/S和互联网应用不断普及,Web 2.0和社会化媒体 以及游戏等大量频繁交互应用普及,相对静止的MVC模式已经不适合高度交互注重行为的应用了。

DDD领域建模本身比较重视结构,它的实体 值对象和服务器是也是一种结构划分,但是没有强调对象职责行为的重要性,而这是对象和数据库唯一的区别,当然其上下文场景概念的提出,也可以认为体现了对角色和场景的重视,但远远不够。

相反,对象设计:角色、责任和协作"(Object Design: Roles, Responsibilities, and Collaborations))一书提出职责驱动开发,将对象行为上升为重点,提出了对象其实是在扮演某种角色,而角色是有职责的,然后会在一定场景上下文环境中实施一定交互行为,这些已经在Jdon进行了充分讨论:
DCI,领域模型,领域事件的一些想法
异步架构思维:使用Akka实现领域建模

该书总结了集中式控制器4大缺点,MVC的控制器实际就属于这种集中式控制器风格:

1.Control logic can get overly complex. 控制器会变得复杂,很多人在Struts的Action控制器中写业务代码已经变得很常见,所有的操作都在action中,有的action都几乎上千行了.

2.Controllers can become dependent on information holders' contents.控制器变得依赖信息数据中心或数据库了,控制器做很多事情,意味着领域对象就做很少事情,控制器最后不是只会做什么,决定战略性的事情,也和怎么做,如何实现等战术问题耦合。

3.Objects can become coupled indirectly through the actions of their controller. 对象将间接地通过控制器的action耦合在一起,一个对象在控制器中查询获得,然后复制给另外一个对象,这两个对象就耦合在一起。

4.The only interesting work is done in the controller.唯一有趣的工作是做控制器,Responsibilities职责被吸进控制器对象,只将一些行为留给角色模型完成,重要的事情都集中在控制器中了。

MVC的控制器是Mediator模式一种,也属于一种集中式控制器,它与观察者模式重大区别是:Mediator模式封装了通讯,而Observer分散通讯,从通讯角度来看,控制器也有其固有的缺陷,容易变成大而全高度耦合的集中器,这些都是为OO所不容。

DCI架构是最近才兴起的新概念,它从一个全新角度来看待软件,与职责驱动设计不谋而合,同时也是对DDD的发展和完善。

DCI是数据Data 场景Context 交互Interactions的简称,它重要贡献是提出了场景这个概念,而这点是职责驱动开发一书没有提及,该书只是否定了MVC,揭露其问题,没有提出替代方案,而DCI正是MVC的替代架构,DCI替代MVC 用场景替代控制器应该是大势所趋,如下图(图来自原文英文The DCI Architecture: A New Vision of Object-Oriented Programming):

场景其实将MVC中Control和模型中一部分挖了出来,以角色场景方式进行重新组合。这是一种与MVC模式考虑角度完全不一样的新角度,这种角度更符合OO。

最近,有人提出 场景Context是新的对象类型,场景不但可以替代SOA的Web服务,也可以替代MVC的控制器。

个人认为:未来新的分层架构可能变成这样:
View --> Context ---> Domain Model ---> Component/Respository

MVC模式已死。

[该贴被admin于2010-04-09 14:22修改过]

这个问题的分析可以从股票软件中就可以看出MVC的严重不足,
动态对象间的交互已经不是单纯的页面与事件的关系,而是跨页面

jsp/asp/这种瘦客户端的技术已经不堪重负,满足不了这种场景,单纯引进一个ajax就是足够的复杂

因此未来的发展我认为胖客户端技术应该更有前景
它在解决MVC,AJAX所要解决的问题上有着先天的优势,并且克服了其不足

请大家拍砖

最近在看Ruby on Rails ,感觉在ORM方面,简直完全没有关系型DB的影子了.但依然是MVC架构,看来它的命运也不乐观吗?

我感觉mvc最重要的好处是在开发较大项目中,
可以让流程中各个模块各司其职。

至于
A、“很多人在Struts的Action控制器中写业务代码”,
只能归咎于2点。
1、写代码的人“修炼”不够。不能理解高内聚低耦合的OO思想主旨
2、项目负责人放任自流。导致代码混乱。

B、“控制器变得依赖信息数据中心或数据库”
现在的MVC应该大概都再用spring这样的IOC容器再对控制器进行分层,诸如service层dao层之类,
说“依赖”,也是应该service和dao之间的依赖。
而且这种依赖是和需求相关的,也就是和业务逻辑相关的,
个人感觉也是一种“合理的存在”

C、“对象将间接地通过控制器的action耦合在一起”
这个“缺点”到很客观。
不过,作为开发整个项目的人来说,
“构架师制定框架,程序员去实现业务逻辑“是“完美的结构”。
DDD对于中小项目可能更有“效率”,
但是对于大项目而言,
可能会让构架师和程序员的工作分工不明确。
构架师过多的考虑业务细节;而程序员则会接触更多,不属于自己的“细节”
这样可能会增加开发成本和带来更多的bug

而“对象和action耦合在一起”,也基本符合具体业务流程设计的思考方式
(就像一串糖葫芦,山楂的就串山楂,山药蛋的就串山药蛋)
(更不能指望需求定制和需求分析人员考虑构架/代码方面的内容)
(没有贬义,的确也不应该他们去考虑这方面的内容)

D、“重要的事情都集中在控制器中”
和B的观点一样,使用spring可以更好的“细化”责任、更好的执行“开闭原则”
好吧,既然是“only interesting”,那就让它“interesting”吧
但不要“only”

这是我对作者4点的一点个人见解,
也许是被MVC“奴役”惯了,
导致思维模式僵化,说话也比较极端。呵呵

当然作为一种技术领域新的概念,
无论有任何发展都是好的。

但是存在就是有价值,
“已死”之类的词还是有点“牵强”,
(也许有一点点点点“哗众取宠”的意思)

servlet出现的时候,perl/php已死
jsp出现的时候,servlet已死
struts2出来的时候,struts1已死

用郭德纲说过的一句话形容
“现在‘黄鹤楼’、‘报菜名’还能让观众笑的前仰后合的...”,呵呵

我经验不多,欢迎大家指正

个人观点,欢迎拍砖

good luck

同意,DCI更符合业务逻辑。
我想知道DCI在JAVA领域除了JF,还有什么好的框架吗?
[该贴被javagens于2010-04-09 14:15修改过]

大家的想法非很让我受益非浅啊。谢谢

熟悉MVC且用过者。都会发现HTTP无状态会给MVC构架带来沉重的打击。
一次性的买卖不是不行的,所以不的不靠多写几个Controller,利用AJAX来维护客户端的状态。
这样的controller又有何意义呢?同时也看不出高内聚的东西在里面.

有点意思

个人感觉还没死,可能有倾向,但是不至于那么快
中国的国情太沉重,要想马上从过程到面向对象的转变很难
我最近做的一个项目就是采用领域的思想(有点牵强,但是绝对要分离mvc跟domain),banq老师说的这个问题就摆在我们面前了,所以,我们一直想搞清楚到底分界在哪里
我们是通过一个门面对象来界限的,但是总是有点不爽,好像不通的样子
还有就是编码的效率问题,这个问题也很困扰我们,我听说play框架做mvc的那种处理速度相当快,我们用了ssi2,很沉重,就好像前辈们说的那个ejb跟spring的区别一样
是不是应该出一个比较优秀的框架了
banq老师的思想真是不错,那种架构方式如果再结合一些规约的话,说不定可以做出世界标准,就像spring那样

banq老师什么时候动手,我想参与,到时给个信息???!!

如果不必像mvc那样沉重分离m-v-c,并且能够在所谓的mvc层进行拆离的话,是不是也能提高一些编码的效率呢
再加上我们nosqldb的涉入,是不是会避免关系型数据库的那种复杂呢???
很有意思啊

最近一直在考虑脱离了关系型数据库,到底如何存储?
看了那些文章和评论自己还是迷茫,唉。。。。归根结底还是没用心去研究啊,再说了公司内部对nosql也没人了解,头大

兄弟们多拍点砖头,我想再清醒点。。。。

个人不赞同以某某已死作为标题,毕竟mvc模式只是对项目代码在逻辑上的一个划分而已,仅为方便从代码层做管理。mvc的诞生源于对代码的放置,正如有一堆东西两个人的放置办法不同,一个人简单的堆积在一起,而另一个人做了分格然后放置。不管怎么放,放置的方法只限于技术层面,放得好的对于下次需要时候选起来要更快更方便仅此而已,由于web在过去几年里的盛行导致了mvc这样的放置方法得以流行,但实际上正如分格放置物品的方法并不只有mvc这一种并且不同性质的行业有不同的放置方法一样,电路板上电子元件的放置不会像物流公司放置快件,常常有个比喻说盖平房和盖楼房的差别,尽管盖楼的设计和初期要考虑的东西要比盖平房的复杂很多,但你做了30层楼的设计以后再有扩展性也仅止于30层,高一层都要对设计做改动。但这并不能说之前使用过的30层的设计方法有问题,你可以从细节上去对以前的设计做细部更正,但却不能否认mvc在过去的it发展里确是不可替代和历史的必然产物,在那段不计架构的日子里mvc是一个可以简单上手快速使一个新手过渡的架构工具,而更早以前在没有模式概念的时候也不是没有模式,人们的开发是多种模式的混用,一半这个模式和一半那个模式的拼装,或4-5个模式混在一起的拼装。后来定义叫做过程开发,再后来过渡到OO开发就有人呼吁过程开发死了,大肆宣扬OO开发,还有人著书大讲特讲“万事皆对象”,这就好像学会跑步就说走路没用一样可笑。
突然想到,我们搞技术的人尚且如此乐此不疲地追逐热点,就难怪中国的房价会只涨不跌了,没人问值不值这个价,有人去我就看看,有很多人去我就跟着去,有面子的人说好那就是好,大家都在没头没脑地追逐着热点。

现在有成熟的dci架构实现吗?

早好几天就看到那篇文章了,可google趋势了一下,发现目前应用并不是很广泛,不知道有没有成熟的应用案例以供学习。

2010年04月12日 12:23 "ranma"的内容
不知道有没有成熟的应用案例以供学习。 ...

其实模式和产品或方案是区别的,模式是比较高瞻远瞩,是非常讲究逻辑和证据,而等一个模式被成熟广泛应用了,它的问题就暴露出来的,因为有形必有缺,MVC模式就是这样,而DCI架构从逻辑上和有影响理论都来支持,相信会有大量成熟应用,现在是你我将DCI投入应用的时候,等DCI架构成熟,也可能是其高峰转折时候,我们会又发现其问题。


微软的Model View ViewModel (MVVM)其实也是对MVC模式的分解,控制器变得可有可无,ViewModel变得非常重要,它起到data binder/converter 数据绑定和转换作用,有点类似Jdonframework中控制器的作用(将Form和Model进行复制)。
[该贴被banq于2010-04-13 12:04修改过]