`
dualface
  • 浏览: 13813 次
  • 性别: Icon_minigender_1
  • 来自: 自贡
文章分类
社区版块
存档分类
最新评论

Web 应用的 MVC 到底和经典 MVC 有什么不同

阅读更多
Web 应用的 MVC 和经典的 MVC 显著不同

MVC 早期出现在桌面应用中。由于桌面应用的各个部分都运行在同一个进程(即便是后来流行的 C/S 应用,很大程度上也可以假想为同一逻辑进程)中,所以应用程序各个部分之间的交互都视为“可信任的”。

经典的 MVC 是 C 返回一个合适的 V。V 里面调用 M 获得数据,如果有什么 UI 上的事件发生,也是 V 里面直接去操作 M 了。因此在经典 MVC 中,应用程序逻辑是主要放到 V 中的。C 只完成应用程序逻辑中的小部分(分发不同的 V)。由于大部分应用程序逻辑是在 V 里面实现,所以 V 还要维持一个内部状态。

就拿大家前面的例子:输入框如果输入错误的数据,应该变成红色。

这个需求是典型的应用程序逻辑(更可以具体为一个 UI 逻辑),所以最好的实现场所就是 V 里面。在经典 MVC 中,控件输入数据会引发一系列的事件,而 V 可以拦截控件的 onchange 事件,从而设置控件的颜色。后来更进一步,将控件封装为对象,从而让控件对象负责自己的逻辑,V 就不用操心这些细节了。


到了 Web 时代,MVC 就变了

最关键的一点就是应程序被分成了浏览器端和服务端两部分。
对 MVC 的影响就是 V 现在也被分成了两部分,一部分放在浏览器端,一部分放在服务端。

还是那个输入框的例子,Web 应用处理起来有多种方式:

1、输入改变后,什么都不管,直到提交表单后,服务端对数据进行验证。如果验证失败,再重新构造整个用户界面,并且将输入框的属性改成红色。这个过程中,V 完全是被动的,仅仅是负责渲染 HTML 而已。
2、输入改变后,通过 Ajax 请求提交这个控件的数据,让服务端对数据进行验证。服务端返回特定的数据(例如一个 JSON)指示验证是否通过,V 里面的 JS 代码则根据返回结果更新输入框的颜色。
3、输入改变后,提交整个表单。然后服务端根据客户端的事件调用服务端的事件处理方法。事件处理方法中对控件数据进行验证,再更新控件的属性。最后服务端重新构造整个页面。
4、输入改变后,客户端的 JS 直接验证并更新控件状态。但整个表单提交到服务器后,还是得一一验证。

第一种是最传统的,也是最常用的。第二种则是 Ajax 兴起后流行的,不过现在大家也在反思这种模式是不是造成太多对服务器的请求。第三种则是 ASP.NET 的 POSTBACK 机制,JSF 我不了解,看介绍也是类似的机制。第四种实际上只是第一种的变形。

第一种模式:浏览器端完全不负责任何逻辑,仅仅是提供一个输入数据的接口,然后可以把数据提交到服务端。应用程序逻辑完全在服务端里面实现。
这种模式里面,V 实际上只是一个模板。服务端的 C 负责响应请求,然后验证浏览器端提交的数据,再调用 M 进行处理。最后根据处理结果,载入模板,渲染出 HTML 返回给浏览器。

第一种模式容易理解,而且实现简单,对浏览器端没有特殊要求,所以一直以来都是最主要的处理模式。但缺点就是用户体验不好,对用户操作不会有及时的反馈,而且没有办法根据用户操作实时的更新 UI。


第二种模式:浏览器端稍微主动点,会把 UI 事件报告给服务端。服务端处理后再反馈特定信息给浏览器端,浏览器端从而可以更新 UI。
比起第一种模式,第二种模式中的 V 会包含一些 JavaScript 代码。这些 JS 代码负责响应 UI 事件,然后把事件及相关的数据传递到服务端,并等待服务端的响应。服务端还是由 C 来处理,只不过处理完成之后仅仅是把处理结果返回给浏览器端(XML、JSON、字符串或者 JS 代码)。浏览器端的 JS 收到服务端的响应后,根据处理结果对 UI 做相应的更新。

这种模式的相对第一种来说有了不小的进步。用户操作可以马上得到反馈,而且可以构造非常动态的 UI。缺点则是需要编写大量的 JS 代码,服务端也要增加对应的响应代码。而且不同浏览器对 JS 的支持程度也不同,实践起来即使有各种 JS 框架的帮助也是比较繁琐的。


第三种模式:这种模式一个页面就是一个表单,JS 会去响应表单中的 UI 事件,然后根据事件类型决定是立即提交整个表单,还是稍后提交。
当表单提交后,服务端就不再是一个常规意义上的 C 来处理了,而是一个页面控制器(可以看作更复杂的 C)。页面控制器会根据定义,构造出整个页面的对象体系(例如 Page 对象中有两个 Textbox 对象)。构造好对象体系后,页面控制器会解析提交的表单中包含的事件。然后调用各个控件的事件响应方法。此时,就和桌面应用非常接近了。我们可以给各个控件编写事件响应代码,并在事件响应代码中调用 M 处理数据。当所有的事件都处理完成后,页面控制器会载入模板,然后传入对象体系,并通过复杂的渲染机制,将 UI 内容渲染出来返回给浏览器。

这种模式的好处很明显,那就是应用程序逻辑都在 V 里面完成。而且控件封装为了对象,控件的逻辑可以自己负责。缺点就是每次提交都是提交整个表单,数据量较大时明显会增加通讯量和延迟。而且早期的 Web 应用事件驱动模型会导致每次提交都重新构造整个页面,用户体验和效率也不怎么样。好在后来都有所改进,使用 Ajax 来提交表单和更新用户界面。


在上述三种模式中,我们会发现一个共同点:绝不在浏览器端实现应用程序逻辑。

因为浏览器端是不可控的运行环境,如果应用程序逻辑在浏览器端实现,那么安全性就得不到保证了。比如批量删除操作这个应用程序逻辑如果在浏览器端实现,用户完全可以自己分析浏览器端的代码和逻辑,直接构造一个表单来提交,从而绕过各种验证。

但是不在浏览器端实现应用程序逻辑,不代表不可以在 V 里面实现应用程序逻辑。要记住在 Web 应用中,V 是可以分成多个部分的,并且分别运行在服务端和浏览器端的,而且在服务端实现 V 也有很多种模式。实际上第三种模式就是典型,V 运行在服务端,并且完成所有的应用程序逻辑。


在服务端 V 中实现应用程序逻辑

比如我们可以在模板中写入应用程序逻辑,然后模板引擎解析模板时,通过嵌入模板的 tag 来调用 M 获得要呈现的数据。这种方式已经非常非常多的实现了,实际应用时对于显示各种数据是很方便的。但是这种模式没办法主动响应用户操作。所以后来出现的事件驱动才是最完整(但不是最完善)的解决方案。

可惜由于 Web 应用的天然特性,事件驱动不管怎么改善,都绕不开将整个表单提交到服务器的过程。所以事件驱动在 Web 应用上一直都没有成为主流。
分享到:
评论
10 楼 bloodrate 2008-11-27  
我觉得对MVC解释狭隘了,MVC,V不见得是给用户显示的最终试图,也有可能你设计一个API,单独用这个API实现不了任何效果,但是在程序中使用了API能带来不少好处,那么你可能把这个API当作你C层中的某个组件,这样看没问题,但是单独来看这个API,这个API完全也可能实现完整的MVC,如果你在你的servlet里写 Something st = Apixxx.showSomething().调用这个API那么很可能意味着你在你整个web程序的C层中调用了API中MVC的V层。所以MVC不意味着是某个可视化程序的框架,也完全有可能是某个组件的全部实现,MVC是林巴斯写的那本软件体系风格书中“分层”风格的最经典的实现,他不限制你就要写可视化的程序,如果你愿意,你完全可以设计一个MVC风格的String类。。。
9 楼 xixix2004 2008-11-24  
LZ属于主观唯心主义.

MVC中各层的功能完全是设计的时候人为定义的,就算是LZ所说的WEB下的MVC,我也可以人为的把各层的功能设计成LZ所说的经典MVC那样,那你说我的这个MVC到底是属于哪一种?
8 楼 netbuddy 2008-11-24  
看老廖的帖子真是一种享受啊,思路清晰,文笔还不错:)
7 楼 dualface 2008-03-28  
MVC 是一系列模式的统称,不是只有一种。你可以去维基看看,我这里上不了。
6 楼 cm4ever 2008-03-28  
我认为MVC只有一种定义,因此没有经典MVC和web应用的MVC差异一说,有不同框架特色的差异之说,如果你的帖子讨论的是不同框架的差异,这个并没什么问题,但是说到经典MVC和web应用的MVC,就有问题了,MVC什么时候还分两个了?
5 楼 dualface 2008-03-28  
我没说这种智能化是经典 MVC 啊。。。。。。

恰恰相反,这种智能化的UI是典型的反模式。


MVC 经典模式里面,V 是有很多逻辑,但只是应用程序逻辑,不是领域(业务)逻辑。这是重点。
4 楼 cm4ever 2008-03-28  
dualface 写道
引用

.net我还没研究,但是他一套框架统一了win form和web form,肯定有其特色。


Eclipse 我不了解就不谈了。但 .net 的框架其实不是像你想的那样是一套,而是好几套。ASP.NET 的 Web Form 和桌面应用的 Win Form 是两个不同的子框架。两者只是都基于事件驱动这种原理。

实际上,Win Form 和 Web Form 都是好心办了坏事。虽然提供了一个极好的基础,但大家都忽略了 M 的存在,把用户界面变成了“智能UI”。

你的意思是这种智能化导致使用微软产品的开发人员继续在事件方法里写业务代码吧,也就是你所说的"经典MVC"那样。
3 楼 dualface 2008-03-28  
引用

.net我还没研究,但是他一套框架统一了win form和web form,肯定有其特色。


Eclipse 我不了解就不谈了。但 .net 的框架其实不是像你想的那样是一套,而是好几套。ASP.NET 的 Web Form 和桌面应用的 Win Form 是两个不同的子框架。两者只是都基于事件驱动这种原理。

实际上,Win Form 和 Web Form 都是好心办了坏事。虽然提供了一个极好的基础,但大家都忽略了 M 的存在,把用户界面变成了“智能UI”。
2 楼 dualface 2008-03-28  
我觉得不是我理解不对哈。是你没有正确理解。我估计你是对我说那个“应用程序逻辑”没理解到。

按照《企业应用架构模式》一书的说法,应用程序逻辑主要是数据的输入输出以及用户交互方面的逻辑。而涉及到业务的逻辑称为领域逻辑。

所以我前面说:

引用
因此在经典 MVC 中,应用程序逻辑是主要放到 V 中的。


是没有问题的。


事实上,即便无数人喊 MVC,但是能把领域逻辑真正给封装到 M 里面去的,是少之又少。绝大部分人都在 C 或者 V 里面就把领域逻辑也给实现了。正如你说的 MFC、wxWeight 等,提供那么多类,本意就是让开发人员可以更好的处理应用程序逻辑,而不是让你把业务逻辑也放到这里去实现。但大家都觉得这样做省事,就不管了。最典型的例子就是 VB。VB 提供了极好的 IDE 和事件驱动开发,结果大家都把领域逻辑在用户界面里面实现了。但事实上,VB 是可以单独写 Model class 来封装领域逻辑的,只是大家不用罢了。

在严格的 MVC 模式中,V + C 负责应用程序逻辑,M 负责领域逻辑,分工相当的明确。
1 楼 cm4ever 2008-03-28  
dualface 写道
Web 应用的 MVC 和经典的 MVC 显著不同

MVC 早期出现在桌面应用中。由于桌面应用的各个部分都运行在同一个进程(即便是后来流行的 C/S 应用,很大程度上也可以假想为同一逻辑进程)中,所以应用程序各个部分之间的交互都视为“可信任的”。

经典的 MVC 是 C 返回一个合适的 V。V 里面调用 M 获得数据,如果有什么 UI 上的事件发生,也是 V 里面直接去操作 M 了。因此在经典 MVC 中,应用程序逻辑是主要放到 V 中的。C 只完成应用程序逻辑中的小部分(分发不同的 V)。由于大部分应用程序逻辑是在 V 里面实现,所以 V 还要维持一个内部状态。

就拿大家前面的例子:输入框如果输入错误的数据,应该变成红色。

这个需求是典型的应用程序逻辑(更可以具体为一个 UI 逻辑),所以最好的实现场所就是 V 里面。在经典 MVC 中,控件输入数据会引发一系列的事件,而 V 可以拦截控件的 onchange 事件,从而设置控件的颜色。后来更进一步,将控件封装为对象,从而让控件对象负责自己的逻辑,V 就不用操心这些细节了。

我觉得你对cs的mvc见解很有问题。
你原文说ui事件发生是在view里进行处理的,你认为mfc/wxWidgets/vcl中CWindow/wxWindow/TForm的继承类仅仅是一个view?

从本质上来讲,对话框类/面板类/Frame类及其子类作为视图类,应该只处理视图方面的工作,但是现实中他们的职责太大了,很多很多程序员在直接对话框的事件方法里写业务处理的代码,sql调用也直接写在里面,这符合mvc吗?

用当下流行的设计模式来思考一下一个对话框类的使用。
1.这些业务处理代码可以封装起来,那么有了dao类。
2.CRUD按钮都需要验证数据完整性,如果每个dao方法都调用一下,好烦,那么给对话框类添加消息处理,判断是CRUD按钮被点击就先执行validate方法。
2.对话框启动时需要初始化界面数据,代码封装起来,在OnInitDialog方法里调用一下。

好了,现在对话框类的功能就出来了,是控制器和视图的混合体。

接着我们可以更进一步:
1.既然每个对话框类初始化时都要将po的数据填充到控件里,那么干脆封装出来。
2.既然每个命令按钮都需要validate,那么也封装出来。
3.既然做业务处理前都需要将所有界面控件的值传到对象中,那么也封装出来。

很有趣的是,我看到wxWidgets封装了这个东西,wxWindow类有一个方法SetValidator,看看wxValidator类的其中三个方法
wxValidator::TransferFromWindow
wxValidator::TransferToWindow
wxValidator::Validate

所以楼主你所描述的经典MVC只能说是国内开发人员的经典手法,算不上对mvc的理解和深入。

我认为,传统cs没有发展出足够好的mvc框架,1是语言限制,2是各种操作系统差异的限制。
bs开发用的都是跨平台脚本语言或者基于虚拟机的语言,自然有很大的发挥余地。

但是java和.net的出现,给cs编程的mvc框架带来了生机。
eclipse的mvc框架,除了在系统数据配置(plugin.xml)方面进化很大,其他方面暂时没发现。
.net我还没研究,但是他一套框架统一了win form和web form,肯定有其特色。

相关推荐

    spring-webmvc-5.0.9 jar包、源码和javadoc

    总结,Spring Web MVC 5.0.9提供了强大的Web应用开发框架,其丰富的功能和注解驱动的开发方式极大地提高了开发效率。通过查阅提供的源码和Javadoc,开发者可以更深入地理解和运用这一框架,实现高效、可维护的Web...

    MVC模式在WEB开发中的应用

    综上所述,MVC设计模式对于提高Web应用程序的质量和效率至关重要。通过将业务逻辑、数据管理和用户界面分离,MVC模式不仅简化了开发过程,还提高了代码的可维护性和可扩展性。对于PHP开发者而言,理解和掌握MVC模式...

    spring-web-5.2.3.RELEASE和spring-webmvc-5.2.3.RELEASE

    Spring Web模块和Spring Web MVC模块是Spring框架中的两个关键组成部分,它们在构建Web应用程序时起着至关重要的作用。 Spring Web模块(spring-web-5.2.3.RELEASE.jar)主要负责提供Web相关的功能支持,包括HTTP...

    JAVA WEB中MVC设计模式

    MVC(Model-View-Controller)设计模式是一种广泛应用于Web应用程序开发的架构模式,它的主要目标是将业务逻辑、数据处理和用户界面分离,从而提高代码的可维护性和可扩展性。在Java Web开发中,MVC模式扮演着至关...

    基于MVC设计模式的WEB应用框架研究

    MVC(Model-View-Controller)设计模式是软件工程中一种广泛应用于Web应用开发的架构模式,尤其在J2EE环境中,它有效地分离了应用程序的不同部分,提高了代码的可维护性和可扩展性。MVC模式的核心思想是将应用分为三...

    spring-webmvc5.3.6 jar包.rar

    当然,如果你的应用使用了独立的MVC框架,则无需这个JAR文件里的任何类。(例如: org.springframework.web.servlet.DispatcherServlet ) spring-webmvc 是 Spring MVC 的一个实现。spriing-webmvc 依赖于 spring-web...

    MVC的JavaScript Web富应用开发(完整版)

    揭开MVC的神秘面纱,教你如何设计合理的架构以及处理应用内部模块之间的依赖 介绍模板引擎和数据绑定 讲解远程数据加载、第二代Ajax以及跨域请求 利用WebSockets和Node构建实时应用 拖拽上传文件以及上传进度...

    基于J2EE的Web应用的MVC架构实现_尹汉东

    设计模式在当前的工程应用中越来越广泛 ,MVC 是软件开发中 的一种重 要的设计 模式 , J2EE 则是... 并构建了一个简 单、实用的 Web 应用框架 , 达到了视图 、控制 、模型的分层 , 成功实现了 J2EE 平台上的 MVC 架构 。

    Spring Web MVC入门教程

    Spring Web MVC是一种基于MVC模式的轻量级Java Web应用框架,它是Spring框架的一部分,主要用于简化Web层的开发。Spring Web MVC允许开发者将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller...

    system.web.mvc

    标题中的"system.web.mvc"指的是ASP.NET MVC框架的一个核心组件,它是Microsoft开发的一款用于构建动态、数据驱动的Web应用程序的库。ASP.NET MVC允许开发者使用Model-View-Controller(MVC)设计模式来分离应用程序...

    System.Web.Mvc 2.0 Dll

    **System.Web.Mvc 2.0 DLL** 是ASP.NET MVC框架的一个关键组件,它为Web应用程序开发提供了模型-视图-控制器(MVC)模式的支持。ASP.NET MVC是一种轻量级、基于模式的Web应用程序开发框架,它允许开发者使用HTML、...

    Spring Web MVC外文翻译

    了解 Spring Web MVC 的核心概念和架构设计,对于理解和开发基于 Spring 的 Web 应用程序至关重要。特别是 DispatcherServlet 的配置及其与 WebApplicationContext 的交互方式,是深入掌握 Spring Web MVC 不可缺少...

    浅析MVC模式在WEB开发中的应用 毕业论文

    在PHP中应用MVC模式,可以采用现成的框架,如Laravel、Symfony或CodeIgniter等,它们提供了成熟的MVC结构和工具。以创建个人Blog为例,控制器负责接收用户的请求,如发表文章、查看文章列表等;模型处理数据的增删改...

    浅析MVC模式在WEB开发中的应用

    总结:MVC模式是Web开发中的一个重要工具,它有助于构建可扩展、可维护的Web应用程序。PHP5及以上的版本为MVC提供了良好的支持,通过理解并熟练运用MVC模式,开发者可以更好地应对复杂Web项目的挑战。在实际应用中,...

    mvc servlet jdbc web框架

    在Web开发领域,"mvc servlet jdbc web框架"是构建基于Java技术的Web应用程序的经典方法。这一模式结合了Model-View-Controller(MVC)设计模式、Servlet技术、JDBC(Java Database Connectivity)以及Web框架的基础...

Global site tag (gtag.js) - Google Analytics