论坛首页 Java企业应用论坛

Ajax把MVC模式变成了"MV模式"

浏览 10334 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-01-05  
你用Visual Studio 6.0做一个MFC窗体应用程序,用工程向导自动生成的框架就是一个Document加一个View,这就是MV模式。
现在谁的机器上装VS6了,试试看。
MV模式其实就是把Controller往View里面塞。
至于unit测试Controller,不知道你到底是在想什么。把Model和Controller、View分开的目的就在于他们混在一起,使得Model无法unit测试。分开了以后Model是绝对不能依赖Controller和View的,这就使得Model可以单独测试了。至于Controller和View,Controller不必测试,他只是一个传声筒;View搞单元测试,还不如直接用眼睛看一下。
如果你觉得你写的Controller和View需要测试,最好是先看看是不是你把很多Model该做的事情放错了地方。
0 请登录后投票
   发表时间:2007-01-05  
总得看来,你把Webwork和Struts的MVC当成了唯一的MVC了,他们这种古怪的设计只是因为HTTP的特点而已--因为HTTP 1.0的请求/响应的特点(无状态连接),模型的变更没办法"推"(或者通知)到View端了. 由于浏览器五花八门的, 不能要求他们统统支持http 1.1,所以只好采用挖洞的办法, 设计个组件放到Browser里保持连接.这个组件就是XMLHTTP.

AJAX的最大特点是什么,是异步更新,核心是什么,XMLHTTPREQUEST,关键事件是什么 OnReadyStateChange嘛. (我猜)由于XMLHTTPREQUEST保持了与服务器的连接,不信你用TCPDUMP抓一下,里面可能有这样些东西( Keep-Alive: timeout=15, max=99 Connection) 所以接受model的更新事件成为了可能.

假设:view.jsp(视图)、action.do(控制器)、model.java(模型)

view.jsp是用户看到的界面,并通过内置的AJAX对象异步方式给action.do发送请求,AJAX.OnReadyStateChange开始监听(其实就是看看HTTP包头吧).

action.do接收到view.jsp发过来的请求(GET或者POST方式),通过Request判断后发送给相应的业务/数据模型model.java

model.java开始执行业务操作,执行完毕直接给view.jsp页面发送数据更新的通知,这个通知的消息有可能是XML封装的数据。

view.jsp页面中AJAX对象的OnReadyStateChange接收到了数据更新通知,根据实际情况用DOM进行页面呈现更新。

正是基于上述理由,我说XMLHTTP可能把Web MVC带回经典MVC的状态.

PS: 我一篇AJAX的文章都没看过的,纯属想像, onReadyStateChange这个词儿是现查的,所以说错了请拍砖.


0 请登录后投票
   发表时间:2007-01-05  
lane_cn 写道
你用Visual Studio 6.0做一个MFC窗体应用程序,用工程向导自动生成的框架就是一个Document加一个View,这就是MV模式。
现在谁的机器上装VS6了,试试看。
MV模式其实就是把Controller往View里面塞。
至于unit测试Controller,不知道你到底是在想什么。把Model和Controller、View分开的目的就在于他们混在一起,使得Model无法unit测试。分开了以后Model是绝对不能依赖Controller和View的,这就使得Model可以单独测试了。至于Controller和View,Controller不必测试,他只是一个传声筒;View搞单元测试,还不如直接用眼睛看一下。
如果你觉得你写的Controller和View需要测试,最好是先看看是不是你把很多Model该做的事情放错了地方。


我谈的MV是Web上面的,谈VC是否有些不恰当呢?其次VC中的Document加view的做法难道就是我说的MV吗?
你用VC建一个MFC工程,然后把View放在CView的子对象里面,把Model放在CDocument的子对象里面,我想问一下当你的Model越大的时候,你怎么办?你是继续派生一个CDocument以产生一个新的Document,还是选择新建一个C++类把Model封装在这个新类里面,然后让Document来调用这些Model呢?我选择后者,如果选择了后者Document的实际作用就是Controller。而且VC的设计难道很好吗?特别是VC的GUI,恐怕远没有Java设计得好。偷偷说一句很多C++程序员虽然不一定认为Java的GUI好,但一定不会认为vC的GUI是C++中最好的。
至于Controller和View的单元测试问题,你提出来用眼睛看比较方便,对这点我也曾经这么认为。但看了《JUnit in action》之后我发现书中很多地方在测试Controller和view。后来我转变了一下看法,如果一个项目是这么开发的:页面编写人员编写页面,业务逻辑编写人员编写业务逻辑。这两种开发是并行进行的,那么页面编写人员在编写完页面之后,难道不对页面测试吗?注意当页面编写人员完成页面编写的时候,业务逻辑还很可能没有写完,而且这个时候连接业务逻辑和页面的Controller肯定是没有写出来的。那么为什么要测Controller?就是因为存在设计臃肿的Controller,一个Controller只有一个两种分支情况你可以用眼睛去看,如果一个Controller庞大到要控制五、六种跳转逻辑(还不包括其他逻辑),你是否能够靠眼睛去看呢?
在我看来单元测试的最大优势是测试的自动化和测试的可重复性。按照很多项目实践Controller和View是完全有必要进行测试的。至于你说用眼睛就可以测试,一个只有"hello world"这样一行代码的View,是可以用眼睛来测试的。只不过,随着项目的进行,每进行一次修改你都要用眼睛去确认一下这个View是不是正确显示了hello world(完全可能显示成了HELLO WORLD),是不是有点麻烦?
View和Controller不是需不需要单元测试,而是如何测试的问题。如果能够雇一帮人不断的为你的View和Controller采用眼睛扫描的方式进行测试,这实际也是在单元测试,只是这个单元测试不是用计算机,而且成本有点高,并且人的眼睛犯错误的几率比较高哦。
0 请登录后投票
   发表时间:2007-01-05  
ray_linn 写道
liujiboy 写道
mv的说法肯定不是什么新玩意,现在又有几个计算机技术是新玩意?
在我以前的项目中我用其他手段也实现了和ajax一样的东西,按照这个说法ajax也不是什么新玩意。
也许是我没有说清楚,我的意思是:采用ajax开发网站,我们可以跳出原有的mvc的框框,采用mv的方式。而这种方式和GUI程序中model和view混杂在一起的编程方式也有不同。这种网站开发中的mv模式,它是松散耦合的,而GUI程序中的mv是紧密耦合的。
mv模式是我为了方便问题的说明下的一个定义,方便后文的引用。类似于“在下文中简称这种方式为MV”。



这种方式和GUI程序中model和view混杂在一起的编程方式也有不同。这种网站开发中的mv模式,它是松散耦合的,而GUI程序中的mv是紧密耦合的。 -----  什么叫混在一起?为什么就松耦合,为什么就是紧耦合? 是不是自己的编程思想有问题?


你列举的情况恰恰说明MVC的回归。从Front Controller或者page controller回归到“古典/经典MVC"因为XMLHTTP成为了可能---客户端可以发出视图事件给控制器,同时可能可以接受模型改变事件。(只是可能)。

解释一下GUI中采用MV可能产生耦合的情况,以我自己的编程经验来说,GUI中采用MV必然导致紧密耦合。请注意,什么是M,什么是V,什么是C。例如一个Swing中的JButton。JButton显示出来就是一个按键,当我对JButton进行点击时,请注意,按键获得了焦点,并且形态要发生一定的变化(通常按键显示出一种凹陷的感觉,并且有黑色的虚线边框,不知道button发生了什么变化的人,按一下按键看看)。
我们来分析一下这个过程。负责显示按键形态的部分显然是V了,记录按键是否获得焦点的一定就是那个M了,那么谁告诉M应该改变状态值,谁又告诉V需要重绘呢?显然是那个C了。
有人说你简直是强词夺理,有这么复杂吗?告诉你JButton是一个对象,对象里面的一个变量记录按键的状态,然后JButton负责重绘。这只是对象的封装,连MV都算不上,怎么扯到MVC上面去了!
冷静点,打开编辑器,调出JButton的代码,看看你说的那个记录按键状态的变量叫什么名字——model!仔细看,model还是一个对象,叫ButtonModel。再看看是如何重绘的。repaint没错吧,repaint之后实际产生作用的是paint,paint是如何画按键的?提示一下有一个叫ButtonUI的玩意,还有一个叫Graphics的玩意。
种种迹象表明Java的Swing是MVC模式的。在JButton这个类中,JButton既不是View,也不是Model,而是一个Controller。在经典的MVC模型中Controller拦截并处理前端的请求,JButton可以说是非常经典。认为JButton不是Controller的实际是被JButton的名字给蒙骗了。
回答GUI中采用MV导致耦合的情况。按照MV的思路也就是将JButton这个对象去掉,将ButtonModel和ButtonUI直接联系起来,会发生什么情况呢?大家不妨把ButtonModel和ButtonUI直接连接起来看看是不是有一个类一下子就变臃肿了,原来不该它干的好多事情需要它来干了。
0 请登录后投票
   发表时间:2007-01-06  
正统的MVC中是把V作为M的Observer,一个变形是模型代理结构(Model-Delegate),代理既提供模型的表现,同时也提供接口用于改变模型,实际上是V和C合并在一起了。M-D有点像lz所说的MV。

一般在web中M和V却是完全隔离的,因为M无法通知V自己改变了。

使用ajax时具体是怎么回事要看传回来的内容,以DWR为例,如果传回来的是json对象,还是需要对页面赋值,这些代码起的就是C的作用呀;如果穿回来的是js语句(在java代码中用DWRUtil.setValues,实际传回的是js,传回后会被直接eval),这种情况下browse端的M和C都不见了,讨论没有意义了。服务器端如果分得比较细的话,可以用java实现MVC,实际V可以被封装,这样写的话可以在web上实现真正的MVC了(M对V的通知可以利用DWREngine.setReverseAjax(true))。

用ajax时服务器端的C还是少不了的吧,否则session怎么处理?难道dwr直接调用manager?session怎么处理,不会出现在manager的方法的参数中吧
0 请登录后投票
   发表时间:2007-01-06  
kenken0y 写道
正统的MVC中是把V作为M的Observer,一个变形是模型代理结构(Model-Delegate),代理既提供模型的表现,同时也提供接口用于改变模型,实际上是V和C合并在一起了。M-D有点像lz所说的MV。

一般在web中M和V却是完全隔离的,因为M无法通知V自己改变了。

使用ajax时具体是怎么回事要看传回来的内容,以DWR为例,如果传回来的是json对象,还是需要对页面赋值,这些代码起的就是C的作用呀;如果穿回来的是js语句(在java代码中用DWRUtil.setValues,实际传回的是js,传回后会被直接eval),这种情况下browse端的M和C都不见了,讨论没有意义了。服务器端如果分得比较细的话,可以用java实现MVC,实际V可以被封装,这样写的话可以在web上实现真正的MVC了(M对V的通知可以利用DWREngine.setReverseAjax(true))。

用ajax时服务器端的C还是少不了的吧,否则session怎么处理?难道dwr直接调用manager?session怎么处理,不会出现在manager的方法的参数中吧

取消C之后最大的问题就是如何处理Session等Web元素,但实际上这个问题是比较容易解决。
我的项目已经解决了这个问题,而且非常漂亮。改天我整理一下思路,发给大家分享。
0 请登录后投票
   发表时间:2007-01-06  
liujiboy 写道
解释一下GUI中采用MV可能产生耦合的情况,以我自己的编程经验来说,GUI中采用MV必然导致紧密耦合。请注意,什么是M,什么是V,什么是C。例如一个Swing中的JButton。JButton显示出来就是一个按键,当我对JButton进行点击时,请注意,按键获得了焦点,并且形态要发生一定的变化(通常按键显示出一种凹陷的感觉,并且有黑色的虚线边框,不知道button发生了什么变化的人,按一下按键看看)。
我们来分析一下这个过程。负责显示按键形态的部分显然是V了,记录按键是否获得焦点的一定就是那个M了,那么谁告诉M应该改变状态值,谁又告诉V需要重绘呢?显然是那个C了。
有人说你简直是强词夺理,有这么复杂吗?告诉你JButton是一个对象,对象里面的一个变量记录按键的状态,然后JButton负责重绘。这只是对象的封装,连MV都算不上,怎么扯到MVC上面去了!
冷静点,打开编辑器,调出JButton的代码,看看你说的那个记录按键状态的变量叫什么名字——model!仔细看,model还是一个对象,叫ButtonModel。再看看是如何重绘的。repaint没错吧,repaint之后实际产生作用的是paint,paint是如何画按键的?提示一下有一个叫ButtonUI的玩意,还有一个叫Graphics的玩意。
种种迹象表明Java的Swing是MVC模式的。在JButton这个类中,JButton既不是View,也不是Model,而是一个Controller。在经典的MVC模型中Controller拦截并处理前端的请求,JButton可以说是非常经典。认为JButton不是Controller的实际是被JButton的名字给蒙骗了。
回答GUI中采用MV导致耦合的情况。按照MV的思路也就是将JButton这个对象去掉,将ButtonModel和ButtonUI直接联系起来,会发生什么情况呢?大家不妨把ButtonModel和ButtonUI直接连接起来看看是不是有一个类一下子就变臃肿了,原来不该它干的好多事情需要它来干了。


你要是这么理解就没什么好谈的了,撤退~~~~
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics