声 明
本章节由网友 withwind 翻译,由笔者负责后期的文章润饰。
--------------------------------------------------
RIA体系结构中的设计模式
在开发传统Web应用的过程中,企业开发中的设计模式是用来解决代码重用问题的。就如同RIA是从传统Web模型层中演化得来的一样,用来构造RIA的设计模式也是由此演化而来的。这里,名词“模式”用来泛指一个软件开发中解决重复设计问题的通用解决方案。
下一部分描述了如何将功能从传统的前端控制器和商业委托模式转移到新的客户端模式。如同所有的软件设计一样,你会根据需要在合适的场合采用适当的模式。这里描述的高阶模式针对了客户端/服务器通讯中的普遍问题;后面的文章将更加详细的讨论这些客户端模式。
两种软件开发中的普遍问题是:如何与业务逻辑沟通和如何实现客户端与服务器的通讯。建立到业务逻辑的通讯,要求业务逻辑不能和表现层耦合过于紧密,以至于一个改动(不管是逻辑上的还是表现上的)会影响到整个应用。与服务器通讯,需要确保每个请求(Request)包含足够的信息和开销来建立安全、会话、或状态管理。你必须确定每个发送给服务器的消息被认为是一个合法的请求,或者检察消息以获取用于整个应用的标识。
很多种语言实现了传统互联网模式,J2EE环境是其中尤为出色的一种。在Java环境中,你经常使用一个商业委托模式来结构化与业务逻辑的沟通。这个模式的最简单的形式是在真实的业务逻辑外面进行一次封装。这个封装将一个由客户端发来的请求转化为一个对业务逻辑组件的适当请求。为了解决与服务器通讯的问题,很多人采用前端控制器模式。这个模式引导所有请求到一个单一控制器文件,来进行安全性验证并建立正确的控制流,这样它可以在一个HTML页面的表单中做出适当的响应。这两种模式经常一起工作于各种复杂结构下。
除了将一些行为从服务器端转移到客户端外,实现一个RIA体系结构与实现一个传统Web客户端并没有很大区别。从应用设计的角度来看,两个高等级的模式被突出出来:Service Brokering(服务中介)和Client Component to Server Communication(客户端组件到服务器的通讯)。服务中介为单独的组件通讯提供了连接器。在客户端组件到服务器的通讯中,通过提供从组件到服务器的连接性取代了页面级别的连接。针对每个组件,提供适当的应用界面逻辑,包括异步事件处理等等。当然,你也可以根据应用的需要在你的客户端和服务器通讯中建立中心化的通讯结构。
服务中介
一个建立应用的主要原则就是:尽量放松业务逻辑和界面逻辑的耦合程度,这样应用程序界面的变化不会影响到业务逻辑,并且业务逻辑不需要了解它怎么被调用的。如上所述,在传统的环境中,你可以用商业委托模式解决这个问题。在富客户端重你需要考虑到组件和服务两方面的需求。
组件的需求如下:
* 为远程服务提供一个标准的借口。(标准触发方法,设置回调等等)。
* 抽象远程服务层,使它可以是本地的或远程的。
* 抽象调用的方式(SOAP,RMI等等)。
* 当掩护访问或匿名访问时,产生混乱。
* 提供对接受上行请求的组件的操作。
* 提供一个连接到服务的场所。
服务需求包括:
* 抽象调用者。
* 提供标准方法来触发回调事件。
一个符合这些需求的设计包含两个种类的类(Class),如图4所示:
图4:服务中介设计模式
第一个类,服务中介,负责建立到远程服务的适当的途径,并维护一个可用的服务列表以及他们的定义。
第二个类是一个桥接组件,它是一个用户界面组件和服务间的管道。这个桥接组件基于服务定义进行初始化,并了解如何能够与一个本地或远程的服务进行通讯,以及如何通过不同的通讯协议安全的进行通讯,和涉及哪些服务等信息。它包括了对组件的操作,所以它能够在成功,失败或是从服务请求更多的信息时,提供对组件的直接回调方法。
图5: 类之间的关系
为了更深刻的理解这个部分,这里以一个简单的银行应用为例。它包括多个用户选项供用户管理他们的账户以及向银行提出查询。这个应用根据上面提到的层次化模型来构建,用户层提供了一个富应用界面来认证用户,使他们能够察看账户余额和交易记录,以及在账户间转移款项,或记录一个用户服务请求。下一部份将描述如何建立界面,并着重描述如何建立客户端到中间件(中间层次)的通讯。
中间层包括远程服务。在银行案例中,你可以拥有一个位于不同服务器的客户请求服务,因为它紧密结合于一个已存在的客户关系管理系统(CRM)。通讯模式的目标是用来阻止客户端界面了解周围包围的服务的具体情况。事实上,你所需要的全部信息就是服务的标识名称,这样你可以通过服务中介请求一个到该服务的连接。
服务中介从描述如何连接到服务的XML文件中加载应用所知道的所有服务,以及用来引用这些服务的标识名称。当界面提交客户服务请求时,服务中介找到标识的定义并生成连接的必要信息,对界面的其他部分抽象处理的细节。
一个按照这样的组织结构建立的客户端拥有极大的灵活性。例如,你可以增强服务中介,使得它能够察觉服务器和远程请求对本地服务的连接状态,而使得用户界面组件不必知晓应用状态,这样允许你创建偶然连接的应用。