【转载】Ajax与MVC

上一篇 / 下一篇  2010-06-16 11:05:17 / 个人分类:开发

 一直以来,表现层的开发在Web应用的讨论中似乎总是一个小角色。Java的开发者们热烈讨论的 Spring,Hibernate,Struts,WorkWeb 也都跟它没有什么关系。技术专家们甚至理直气壮的喊出了Web表现层应当“As thin as possible”的口号,于是越来越多的人们开始深信有关业务逻辑的开发技术是武学之正宗,而表现层的开发技术只不过是些旁门左道,花拳绣腿。直到2005年初,伴随着 Ajax 的出现,Google Map 等一批样板工程摆到了我们的面前,大家才猛然发现原来Web应用还可以做成这样!在这股冲击下越来越多的人开始考虑表现层的真正价值了。于是 Ajax 迅速的窜红起来,成为这两年Web技术发展道路上的标志性名词。其实 Ajax 即不是新技术也不是很复杂的技术,它不过是基于Web的RIA应用中的一个操作特性(或技术特性)而已。Ajax 只有结合了 Widget (指各种各样的界面组件)之后才能真正的发挥威力。尽管如此 Ajax 的诞生仍然谓革命性的。说道 Ajax 的革命性,可能很多人会大吃一惊:Ajax 不就是 XMLHttp 吗?这种技术早在1999年就出现在浏览器当中了,它不过是一种新瓶装旧酒的噱头! 其实我所说的革命性,并不是指Ajax在技术上是革命性的,而是说 Ajax 的出现对传统 Web 应用的开发模式的冲击是革命性的。

冲击 - 尴尬的 Struts 和 WebWork

  说到这一点,让我们先来看一下目前流行的开发模式,即基于 Model2 的 MVC 开发模式。在 Model2 的眼里存在着这样一个基本的假设,哪就是 Web 应用的运行逻辑是由一系列的页面切换构成的,这里的每一个页面一般来讲都不是特别复杂,往往有着非常特定的功能和目的。同时页面对于浏览器来说又是不可分割的最小单元,要更新页面中的数据必须对页面进行整体刷新。让我们先啦看一个“产品信息维护功能”的例子,现在我们需要维护一个产品信息的列表,用户可以在这里完成对产品信息的CRUD四种操作。在 Model2 中通常的设计方式是这样,我们至少需要编写两个页面,一个用来根据查询条件列出产品列表,另一个用于对单个产品的详细信息进行维护。最终通过这两个页面的交替协作完成所有的功能。假设用户今天要进行如下的操作:输入查询条件查询他所关心的产品,然后修改其中的两个产品,新增一个,最后删除一个。基于上面的设计最终要走完这个流程我们的系统做了些什么呢? 在这一系列并不复杂的操作中,用户界面却足足的刷新了8次!每一次刷新都一位着用户需要等待和重新适应新出现的页面,思维和操作至少会被刷新打断2秒!不难想象一个原本正心情愉悦的打算开始一天工作的用户在经历了这8次的打断之后肯定会倍感挫折。而这只是他一天工作的开始,更复杂的还在后面呢!

那么结合了 Ajax 的表现层又会如何来处理这个问题呢?利用 Ajax 的通信机制结合一套好的 Widget (UI组件),我们完全可以吧上面所有的这些操作都合并到一个界面当中。如果产品信息并不复杂,我们可以使用一个可编辑的 Grid 组件,让用户直接在 Grid 中进行产品信息的维护。如果产品信息比较复杂,那么我们可以在界面上再放置一个产品信息的维护清单,用户可以直接在 Grid 中选择要编辑的产品。所有这些编辑操作的结果都会暂时的缓存在客户端,直到用户完成了上面的各个步骤再一次性的利用 Ajax 技术提交到后台。这样,再整个操作过程中用户始终不需要离开这个界面。



由上面的分析可见,Ajax 一出场就推翻了 Model2 的基本假设,用户的操作体验已经不再由一系列的页面切换所组成了。因此表现层的开发技术的升级必须导致对 MVC 设计模式的重新思考和定位。如上图,在传统的Web应用中,我们会很容易找到 Struts / WebWork 在其中的价值所在。应用中存在着大量的网页流,我们需要一种有效的机制对它进行管理。同时因为表现层的功能相对比较薄弱,控制器往往还要承担谓表现层准备数据的工作。这些在控制器中准备好的数据一般都利用上下文 (如 Request 的 Attribute)以推的方式交给表现层,即推模式(Push Model)。

这种推模式在页面总是以整体刷新的方式获得更新的开发模式中并不会出现什么问题,看起来一切都可以良好的运转。可是 Ajax 出现以后,这种运转机制就会出现问题。因为 Ajax 强调的是减少页面的整体刷新,取而代之的是数据的局部刷新。当一个局部数据刷新的请求从客户端被发起时,表现层必须有能力主动的获取所需要的数据。这种操作类似于客户端通过表现层从后端的数据模型中拉取数据,即拉模式(Pull Model )。这一功能需求又与传统的 Model2 的思路产生了抵触。

回顾上面的分析,我们已经在传统的 Model2 和 Ajax 之间找到了两个冲突点:

对页面流的基本假设不同 
推模式和拉模式的矛盾 
重构 MVC 开发框架



   Model2 和 Ajax 之间存在着不可调和的矛盾。但是并不是说我们就必须全盘否定掉传统的 MVC 开发模式。事实上,企业在过渡到 Ajax 的过程中,目前 MVC 开发框架中的主体仍然可以保留下来,只是我们需要对其中的局部进行一些调整。我们称这个过程为对 MVC 开发框架的重构。

   在这个重构的过程当中,首当其冲面临调整的就是控制层,我们需要重新为控制层找到一个定位。如果说在传统的 Web 应用开发模式中控制层的作用是解耦数据模型和页面的话,那么在新的表现层技术引进之后,控制层的作用就应该是解耦数据模型和表现层的数据接口。如此一来Server端的表现层逻辑就全面接管了与Client端的通信,对于Client端来讲控制层就被隐藏到了表现层的后面,只负责表现层与数据模型之间的对接。相应的,原来 MVC 架构与Client端形成的三角关系也就演变成了垂直分布的三键模式。

如果以这里提出的新 MVC 架构结合目前比较流行的 Java HSS 开发模式(即 Hibernate+Spring+Struts / WebWork)。那么在后端的数据持久化和业务逻辑对象(BO)这两个环节的设计几乎就不会收到机阿构重构的任何影响。在 Hibernate 和重构点之间至少有BO作为隔离墙,使用Spring来实现数据模型和表现层之间的衔接也就是一种顺理成章的设计了。如此一来Spring就全面接管了新控制层的实现,Struts / WebWork 的核心价值在这里受到了强烈的冲击。尽管我们仍然可以将 Struts / WebWork 引入到表现层与客户端之间,用于一些整体上的控制,例如权限的校验等。但是这样的使用方法相比骑它们最初的设计思路而言就多少显得有些尴尬了。

   表现层中的构架模式


   以往我们只习惯与讨论Server端的架构模式,在国内一些知名的技术论坛上这一类的讨论空前的热烈。而现在我们有必要再来讨论一下表现层中的构架模式了。因为随着技术的发展,表现层的功能和设计已经变得越来越复杂,现在已经不再是那个表现层只有HTML的年代了。从前面的提到的“重构后的MVC架构”的图中,我们不难发现再新的设计中,表现层已经成为一个跨越Server端和Client端的子系统,在这里既有对UI组件的管理,又有对 Ajax 通信的封装。它的复杂度甚至已经超过了原本被我们认为绝对核心的业务逻辑层和持久化层。所以进一步将MVC 设计模式引入到表现层中已经成为一个非常现实的话题了。



在继续这个话题前让我们先来看看经典的《 Ajax in Action 》中提到的 Ajax 交互的三种类型:

以内容为中心的交互 - 即通过 Ajax 进行交互的内容是 HTML; 
以脚本为中心的交互 - 即通过 Ajax 传递内容的是可用于执行的脚本; 
以数据为中心的交互 - 即通过 Ajax 传递内容的是用于展现的数据。 
事实上我们可以认为这就是 Ajax 应用发展的三个阶段。因为从“内容”到“脚本”到“数据”的发展过程意味着我们必须为表现层提供越来越多的基础代码和框架支持。每一个阶段的抽象度都高于前一个阶段。最终的目的就是实现UI组件和数据的彻底分离,这一目的正是 MVC所倡导的数据与表现的分离。

目前,由于 Ajax 诞生的时间还不长,所以很多 Ajax 的应用还处于相对简单的“以内容为中心”的阶段。这种交互又被称为 Ajah(Asynchronous JavaScript. and HTML)。这种开发方式对现有 MVC 的影响较小,但能够起到改善交互性的作用也非常有限。因此只能算作是一种过渡的模式。从发展的角度来看,MIS类企业Web应用开发的主流一定会走到“以数据为中心”的阶段。“以数据为中心”的表现层应用才是真正具有生命力的,以下我们称之为数据模型驱动型表现层。

那么怎样才能实现一套数据驱动模型表现层的开发框架呢?对于大多数企业来说是很难独立的发展出符合这一要求的框架的。因为发展出一个完整的成熟的表现层开发框架将会涉及到大量的技术累计和时间。这种付出对于大多数的企业来说是不可接受的,事实上也是完全没有必要的。我们可以借助强有力的第三方框架或者组件库。就像在Server端我们需要Spring,Hibernate等来帮助我们搭建框架一样。

随着 Ajax 的持续火爆,各种 Ajax 的第三方框架和组件库也在不断的涌出。不过在这些产品中真正能够直接帮助我们实现数据驱动模型表现层的并不多。像 Backbase, Bindows, DOJO, YUI, Qoodoo 这些产品都基本仍是以提供丰富的UI组件作为其主体设计思路,在这些产品中都缺少一种机制真正的将表现层中的数据管理起来,因此这些产品的表现形式是一些看起来相对独立的UI组件。这类产品习惯上称为“离散控件集”。

在表现层中实现一个真正 MVC 模式应当是数据模型驱动型表现层的基本要件。让我们尝试换个角度分析问题,我们可以把Server端中 MVC 的各个组成部分看成是相对独立的封闭子系统。这个子系统的功能就是从数库中提取相应的数据经过一系列的处理过程然后交给Client端,同时对Client端提交的数据进行一系列的处理过程然后保存到数据库中去。同样我们可以把Cient端的 MVC 的各个组成部分看作是独立的子系统,它所完成的工作事实上就是跟Server端的子系统非常的相似,只不过这个子系统的两个交互的对象是用户和Server端。按照这种思路,最终形成的Web开发模式将是一种迭代的 MVC 架构。目前的 Dorado 产品就是基于数据模型驱动型表现层框架开发的。

  写在最后 
  Ajax 虽然是一种新瓶装旧酒的技术,可是它的价值已经得到了各大厂商和技术社区的认可。预计在今后的一段时间内 Ajax 仍然会持续的火热下去。同时,其他的一些表现层的相关技术也会不时的冒出来。目前除了 Ajax 之外,您也可以给 Comet 投入一点关注的目光,这是一种利用不间断的 Response 的技巧实现的推技术。通过它我们可以制作出一些对实时性要求较高的Web应用,例如:WebIM,Web状态监控,股票信息等。此外还有 Canvas 技术,它让我们可以在浏览器中实现图形绘制功能。也许是这场由 Ajax 导演的表现层的革命来得太过突然了,很多开发人员和企业似乎都还没有做好迎接它的准备。“作界面是美工的事情”,“好的技术人员应该区开发后台”这些仍然是很有市场的想法。在一切追求“科技以人为本”的今天,如果您和您的企业能够尽早的认识到表现层的重要性并适时的作出调整,那么一定会有更大的机会登上市场竞争的制高点。

TAG:

 

评分:0

我来说两句

Open Toolbar