1.基于浏览器的客户机 基于浏览器的用户接口客户机相当于J2EE中基于浏览器的客户机。它们不受限于Web 浏览器.而是同样支持其他形式的标记语言.如面向蜂窝电话的无线应用协议(WAP)的 无线标记语訏(WML)。标记语言在这种情况下是不同的(也就是WML),但仍然可以采 用用于交付内容的相同的机制-也就是说,servlet和JavaServer Page (JSP)的组合。 对于信息交换,基于浏览器的客户机使用标准的方法(也就是客户机方的商业Web 浏览器.将TCP/丨P上的HTTP作为网络协议,以及服务器方的Javaserv丨et和JSP),并使 用公共数据格式(也就是超文本文件和样式表单)。为了使客户机比较瘦,大多数表示逻辑都是在服务器上实现的,这提高了创建可以在不同厂商的不同版本浏览器间移棺的接口 的机会。 甚于浏览器的客户机主要用于: • 支持浏览器并且具有传统输入设备(如笔,键盘和鼠标)的设备。 • 显示很容易用标记语言表示、用浏览器渲染以及大概还能用插件进行补充的内容 的应用。 浏览器最初是为台式机设计的——使电脑成为最佳的目标设备——但今天的移动设 备也支持浏览器。 某些限制条件限制了基于浏览器的接口的使用。例如在设计时,它们并不总是能够充 分利用宝贵的资源,如可用的屏幕上的实际元素,而且浏览器模型仅支持围绕HTTP请求 /响应周期构逑的有限的用户交互类型。此外,基于浏览器的接口并不适合于所有移动设备, 因为对于某些移动设备来说不存在浏览器;当存在浏览器时,它们可能缺乏对帧、图形和 JavaScript这苎维本特性的支持。 2.基于Web的定制客户机 基于Web的定制用户接口更加复杂。这种类型的客户机不同于定制的客户机,在J2EE 中.定制的客户机是个单独的程序,该程序实现所有的表示逻辑,并通IIOP协议使用远程调用方法,直接与业务逻辑(也就是EJB)交互。基于Web的定制客户机也是•个 单独的程序,但与定制的J2EE客户机不同,它使用HTTP与服务器通信并与Web层实体 交互,如servlet和JSP,这与基于浏览器的客户机的方法相同。 在本地幵发环境中为某一个特定的设备或某类设备编写基于Web的定制客户机代码。 由于用户接口是单独的程序.因此在可以支持的用户交互方面,这给U1设计人员提供了 最大限度的*,并且可能会最佳地利用资源,如屏幕上的实际元尜。不利的方面的就是 开发成本会提商。 Luther构架试着将必须编写以创建一个基于Web的定制客户机的本地代码的数量降到 最低,该客户机具有•个支持这种类型接口的框架,如阁17.6所示。基本卜.,该框架对在 多个应用间黹耍的元素进行标准化,包括会话管理、身份验证,对创建和序列化客户机或 Web容器(或两者兼有)上的表示逻辑的支持.从大体上说,客户机是个瘦的、单独的 程序,它创建并布置本地UI构件。它还实现了一小部分表示逻辑,如输入验证和表格显 示的分类。与基于浏览器的客户机•样,大量的表示逻辑实现在了由客户机框架所管理的 组件中的Web层上。 与其他类型的定制用户接口相比,基于Web的定制客户机有很多优势„首先,它们是 癀的。换句话说就是,与胖客户机(也就是所有表示逻辑都实现在客户端层中的定制程序) 相比,瘦客户机相对较小、易于维护,且能够更轻松地在设备间移植。第二,它们使用 HTTP与Web层交互,这与使用IIOP上的RMI的J2EE定制客户机不同。这使得它们更 适合于非Java实现,并且可以更简单地通过无线网实现。 为每个设备上的每个应用创建一个定制的、本地用户接口的代价太昂贵,即使只给少 数几台设各创建也是如此.解决这•问题的方法是根据特性对接口设备进行归类。对于每 -类设备,都要按以前描述的那样设计并实现•个高逼真性的接口。客户机框架减轻了在 某类设备间实现该接口的负担。同样,通过在Web层实现表示逻辑的重耍部分,相同类中 的客户机设备就可以使用该软件,因此共享了其实现的重要部分。最后,客户机框架引入 了允许设备宣扬其接口特征的特性。Web层中的表示逻辑可以获得该信息,这样,在将内 容交付给客户机前.就可以对其进行小的修改。 17.3.2应用 在Luther构架中,应用负责把系统结合成一个功能实体,并暴露-个用于与其进行交 互的API。用户接口调用此API,以为最终用户提供这些特性。 应用驻留在任意数量的用户接口和任意数量的组件之间。应用把n个组件连接在 起,并为n个用户接口提供聚合的“应用”功能。应用是“用户接口不可知的”,这意味 着它们暴遝了任何用户接口可以使用的功能。每个接口都可以暴露所有或部分功能,视情 况而定。例如,运行在像Windows CE这样的移动客户机上的用户接口并不能暴露运行在 台式机上的用户接口所能暴露的管理特性。建议暴露可以在系统中执行的所有功能,每个 用户接口都确定了将哪些功能暴露给用户以及将提供的方法。 快速开发和部署要求设计尽可能瘦的应用。可以通过把大部分业务工作委派给组件来 实现上述目标(在下•节讨论)。将应用代码移动到组件中的标准非常简单:功能是可重 用的吗?如果是,就应该对其进行泛化(以提高可重用性)并实现为组件。另•方面,如 果不太可能重用某项功能,就将其集成到该应用中。 应用的基本元素包括如下内容: • 应用编程接口。系统暴露给用户接口的功能的正面。请注意,通过API传输的数据是元数据(XML)而非特定于表示的数据(如HTML〉。 • 会话状态。当用户进行验证时进行初始化.会话状态一直存在,直到客户端程序 结朿。J2EE简化了状态管理,因为容器支持验证和授权以及会话状态的存储和检 索。应用只是确定需要在请求中持续的数据,并进行适当的调用以存储和对其进行检索。 • 特定于应用的业务逻辑。对该应用独有且不能在其他应用中使用的任何逻辑。 • 组件委派。将工作委派给组件的代码。一般说来.这可以通过业务委派设计模式 实现。 这些元素是应用“预期期望的变更”战术和相关的用于可修改性的“分离用户接口” 战术的结果。 根本不需要改变应用层或组件就可以创建一个新的用户接口。可以把组件的一个新实 现集成到系统中,不需耍影响应用层或用户接口。可以通过集成另个组件,向应用层中 添加必要的API方法以及向每个用户接口中添加新特性以暴露新功能的方式,来向系统中 添加新功能。 17*3.3组件 组件后面的目的是它代表用于重用的元素。因此,策略就是创建•个组件库.然后用 这些组件快速轻松地合成应用,以为客户创建专门的解决方案。组件库中包含与客户机和 服务器框架相关的“核心”组件;针对某些领域的特定领域组件,如维护、修复和检杏;以 及应用程序可能需要填充功能的通用能力(也就是实用程序)组件,如安全性,授权和用 户管理。 Imnedius的策略就是为Luther构架框架和特定的客户领域,逐渐发展个巨人的、面 向特定领域的核心通用能力组件痄。因此.应用开发就变成了创建业务逻辑,该业务逻辑 为客户将必要的能力组件集组合为定制解决方案。 在软件产品线构建中,开发公共组件是•个中心主题,它代表了面向可修改性的“抽 象公共服务”的密集型应用——在这种情况下,就是产生新的解决方案的能力。 ①业务委派担当某个组件的正面一它査找该组件,井使应用的其他部分获得该功能.这样,只需要关 心业务逻辑如何杏找和汸问组件,对应用的其他部分隐藏这些细节。例如,如果组件被实现为ejb, 业务委派就执行必须的Java命名和目录接口(Java Naming and Directory Interface. JNDI)查询并缩小EJB的远程接口,组件被实现为EJB的事实仍然是隐藏的。应用不负责组件生命期的管理,因为J2EE 容器执行该功能.然而,因为它进行委派工作,因此它必须选择要使用哪个(些)组件.应用还括 管理组件交互和组件间关系的逻辑。很明显.此类逻辑应归入应用。遵从此规则简化了组件的实现. 并把绀件间的依赖降到了最低.. 1.组件设计 设计组件的策略就是在任何可能的地方,对组件的API和行为使用设计标准。例如, Inmedius工作流组件(以后进行描述)就是工作流管理联盟(Workflow Management Coalition)的工作流功能和行为规范的实例化。该设计策略允许Inmedius用符合相同的能 力规范的任何其他厂商生产的组件来更换自己的组件。它有利于Inmedius对组件库进行扩 展,将此类组件包括在内。 2.能力划分 绀件库中可能不包含开发中的给定应用所要求的能力组件。必须决定是设计该能力组 件并将其实现为应用的一部分,还是将其设计并实现为一个新的、可重用的组件. 关键的启发式设计是,此能力是该特定解决方案的应用业务逻辑的一部分,还是可以 .在其他应用中使用的更通用能力的•个实例。 3.组件打包 Luther中的任何应用都使用J2EE环境和它的服务。考虑到这_限制,可以将该环境 中的组件打包为EJB、Java bean组件、单个的Java类库、applet、scrvlet或它们的某些组 合。换句话说就是,组件与EJB并不是同义词,而是可以用各种方式对其进行打包。 对给定能力进行打包的策略取决于所使用的J2EE服务以及在大量关键因素之间所做 的权衡(例如,对象间通信的频率、对象实例的位置以及对J2EE服务的需要(如事务以 及多个用户会话间对象状态的持久性)。例如,与EJB的通信是通过RMI进行的,RM1 是一种甩量级的通信机制。在用作J2EE容器中,如果通信是在相同的Java虚拟机(JVM) 内进行的.则要对与EJB的通信进行优化(优化为本地方法调用)„然而,由于J2EE容器 并不要求进行优化,因此EJB之间的通信总是会潜在地提高成本,所以如果性能是个问 題的话,不要轻易地采用它。替代方案就是创建•个java类库,以避免对RM1的需要(和 幵销)。然而,这也迫使组件承担了以前由该容器所处理的额外的责任,如创建和删除组 件实例。 用户必须能够在会话中访问与某个组件关联的对象。对象可能会在该时间内发生变 化..但数据必须持久并在各会话间保持一致。因此,组件通常要求事务。多个用户可以同 时访问相同的对象,很可能是出于相同的目的,必须能够优雅地处理这.切。支持事务能 够使数据库状态一致,从而可以轻松优雅地从故障中恢复过来。 正如在第16章所讲的,EJB模彻支持几个bean类型,包括实体bean,会话bean和无 状态会话bean。不同的类型旨在支持不同形式的业务逻辑,它们由该容器进行不同的处理。 例如,实体bean在如下二者之间做出选择:通过由该容器支持的回叫来管理持久性(也 就是由bean管理的持久性),或者让容器做这件事情(也就是由容器管埋的持久性)。在 任何情况下,都会有很大数量的开销,这限制了在实际中只能把实体bean用在由粗粒度数据访问所刻画的生命期很长的业务实体上。 4. J2EE容器所提供的功能 应用程序要求提供几个能力.如事务支持、安全性和负载平衡。这些能力非常复杂(实 际上,许多公司都围绕提供这些能力来组织其整个业务),属于给定应用或应用领域之外 的范围。Imedius决定使用J2EE构建Luther的个主要驱动因素是商业可用的J2EE兼容 容器提供了这畔特性,因此Imnedius没必要实现它们。 可以在应用部署时为单个的EJB配置这些能力,或者由J2EE容器透明地将它们提供 给EJB。在任何情况F, EJB开发人员都没必要将对它们的调用直接嵌入到代码中,以能 够为给定客户对其进行轻松配置。这不仅促进了独立于应用的EJB组件的创建,而且保证 了组件将会在所对J2EE兼容的容器中成功运行。 • EJB容器以两种方式提供事务支持:由容器执行所有的授权检验(dedaratively), 在程序中进行授权检査(programmatically)。组件开发人员可以通过在程序中进 行授权检査来与容器交互,以提供细粒度的、硬编码的EJB事务支持-开发人员 还可以通过由容器执行所有的授权检验.通过部署描述符来指定EJB方法应该如 何在事务内表现。这能够使事务在不同的应用中以不同方式表现.不需耍EJB直 接在代码中实现或配置它们。 • J2EE提供了一个跨越Web和EJB容器的集成的安全模型。像事务支持样,可 以用由容器执行的授权校验的方式或在程序中进行授权检杳的方式使用安全特 性。如果方法被编写为包括执行它们所要求的许可的定义,那么,开发人员就可 以在部署描述符中指定允许哪些用户(或用户群)进行方法访问。否则,可以使 用部署描述符中的条目用由容器执行授权检验的方式将访问权与方法关联起来。 而且,这使得组件方法具有由该应用所确定的任意的许可,无需重新编写组件。 • EJB容器还提供了透明的负载平衡。FJB实例由该容器在运行时创建和管理:也 就是说,它们根据需要创建、激活、钝化和删除.如果某个EIB最近没有被访问 到,则它可能会被钝化,这意味着其数据将被保存到持久存储器中,该实例也将 从内存中删除这样,容器就在其所有实例中有效地执行了负钱平衡.从而管理资源消耗并优化系统性能。 5.组件开发人员所提供的功能 组件开发人员提供组件的客户视图或API以及组件实现。对于简单的EJB,这等于仅 需耍编写3个类:本地接口、远程接口和实现类。 组件幵发人员还通过API提供了暴露给客户机的数据类型的定义。这些被实现为额外 的类,并通常采取API在EJB之间来回传递的值对象的形式。 17.3.4可重用组件的示例:工作流 在本节中,我们将考虑一个为Inmedius组件库幵发的可重用能力组件,它所提出的问 题以及所做出的决策。工作流组件是迄今为止所创建的最大的能力组件,它是如何设计通 用能力并对其进行打包以包含在Luther构架中的•个示例。 1.设计原理 工作流组件的主要责任是允许客户机对工作流进行建模,然后在其中移动数字制品。 组件还必须允许客户机定义资源,然后把它们分配给工作流活动。很自然地.组件必须具 有极高的可重用性和可扩展性,这意味巷它应该提供通用的工作流能力;提供•个将使用 该组件的应用的操作淸晰且通用的模型:并且对于可能会在特定的工作流实例中移动的数 字制品来说是不可知的。具备完整功能的工作流组件的创建要求使用复杂的用语,如分支 (branching)、合并和衔接(looping)。-般说来.实现工作流能力是一项非常复杂的任务。 Inmedius面临着一个困难的选择,因为在其应用中需要工作流能力,但许多因素都阻 止了它们的完整实现。 • 完整的工作流能力的规模和复杂性超出了 Inmedius的资源范围。 • 完整的工作流能力并不是核心业务目标或核心能力。 • 其他公司已经构建了更完整的解决方案。 长期的解决方案就是与为J2EE应用提供组件化工作流能力的组织建立联盟。然而, 在建立该联盟后,Inmedius必须实现该能力的一个了•集以部署解决方案。 因此,所采用的策略就足设计•个在随后可以用另外一家组织开发的更完整的组件轻 松更换的组件。这就产生了对标准的工作流组件接口的需要。请注意在这种悄况下ABC 如何工作。Luther构架的设计打幵了个新的商机(工作流管理〉,Inmedius必须做出进 入该市场的明确的业务决策。Inmedius确定这已超出了其核心能力。 工作流管理联盟已经开发了一组功能和行为工作流规范.这已得到了工作流团体的承 认。Inmedius设计师根据这些规范构建了其组件.然而仅实现了对当前应用的使用来说所 必要的功能。 该策略利用了工作流团体及其所有活动的知识和经验。该团体已经定义了业务对象及 对象之间的关系,因此Inmedius没必耍重新定义它们。第二,通过坚持工作流管理联盟的 规范,现在,丨nmedius可以使用另外家厂商生产的组件代替其工作流组件,如果客户要 求在Inmedius组件中没有提供的某些功能,仅需要做最少的工作即可。 两个工作流管理联盟规范描述了两个主要的元素:工作流模型的定义以及其运行时实 例的表示(参见图17.7)。工作流模型定义由一个或多个进程定义组成,其中每个进程都由活动定义和这些活动及所有参与资源之间的转换组成。在每个进程定义中,进程管理器 检查-个特定进程定义的所有运行时实例:每个运行时实例维护关于已经完成哪些活动、 哪些活动已被激活、谁分配了这些活动,以及在进程处于活动状态时,工作流组件做出决 策所需要的上下文数据。 Imnedius所关注的个问题是并发。是否应该允许多个用户同时修改个工作流模型 定义?如果存在活动的运行时实例.是否应该允许用户修改工作流模型定义?如果其定义 己经被修改,是否应该允许用户开始一个新的工作流?给定该实现,对上述任何个问题 的肯定回答都会引发•个重要的问题,这是由定义和其运行时实例之间的关系造成的。结 果是,任何解决方案都必须防止这些情况的发生。 因为以前描述的每个情况中的根本问题都是围绕修改工作流模型定义来解决的,因此 解决方案就是把一个锁与其关联起来。为了修改定义.用户必须获得•个锁。对-个给定 的定义来说,只能有•个锁,如果该定义有任何相关的活动运行时实例,就不能得到该锁。 此外,如果工作流模彻定义被锁定,那么,就不能开始一个新的运行时实例。 打包 工作流组件被打包为两个EJB:用于管埋工作流模型定义实例的无状态会话bean:用 于管理定义本身的单个实体bean (参见图丨7.8〉。用这种方式对组件进行打包的决策非常 依赖于不同EJB的特性。 实体EJB在应用中实现表示共享资源的抽象,在这里,持久的对象数据在许多组件和 用户之间共孪。工作流模型定义仅表示了这样的-个共享资源——也就是可以被多次实例 化的进程的定义。在丨nmedius应用中,任何位置的任何用户都可以根据这个单-的工作流 模型定义开始一个新的进程,并参与到其活动当中。 会话EJB模型对状态和行为进行建模。例如,新工作流模型的定义、工作流模型实例 的创建、活动的创建、给活动分配资源以及活动的完成都是通过工作流实例生命期或会话 过程提供给用户的服务。因此.很自然地,工作流实例大部分都是由会话EJB实现的。 一旦决定使工作流实例管理器成为会话EJB,就必须做出使会话EJB有状态还是无状 态的的决定。这取决于要维护的状态的特性。典型地,状态会话EJB为与其有一个对话的 客户机维持状态。然而,运行时工作流实例的状态不是仅由一个客户机操纵的,而是由许 多客户机更新的,包括那些参与实际的工作流进程的客户机,以及应该监视进程并对其结 果进行分析的管理器。结果是,工作流实例管理器被实现为无状态的会话EJB,它比状态 会话EJB更加简单和可扩充,它代表一个给定的客户机保持数据库中的状态,其中所有其 他的客户机都有权访问它。 所关注的另外•个设计权衡就是如何打包工作流模型定义中的单个对象。是否应该将 它们打包为实体EJB?它们是否应该由使用其他某个结构打包的Java类组成(如库)?因 为这些对象彼此交互且互相依赖,因此将它们打包为实体EJB会经常要求在应用中査找并 保留多个EJB句柄.从而产生了大量的开销。此外,我们知道对EJB的任何方法调用本质 上都是RM丨调用,开销是相当大的。尽管大多数J2EE容器都可以确定方法调用是否在相 同的Java虚拟机中,因此将其优化为本地方法调用,但这并不能得到保证。因此.设计决 策就是为应用中的粗粒度抽象创建实体EJB,如工作流模型定义,并将实体EJB本身中更 细粒度的抽象实现为Java类库——所有这一切都是为了减少与重量级的实体EJB关系相 关的开销。 在工作流组件中,这种类型的设计决策的一个示例就是确定在哪儿査找确定是否批准 锁定工作流模型定义请求的逻辑。最初,该逻辑放在实现工作流模型定义的实体EJB中, 将会直接向实体EJB做出锁定定义的请求,它将确定是否批准该锁定(如果是,将其锁定)。 当需要增强业务逻辑.以使得只有不存在活动运行时工作流实例时才能准予锁定,这 时问题就出现了-提供运行时工作流实例信息的方法在无状态会话EJB上定义,无状态会 话EJB是与该实体JEB交互的对象。看起来将对无状态会话EJB的引用传递到实体EJB 中并不合适——首先,因为实体EJB知道它所处的环境(因此妨碍了重用):第二,因为 由该实体EJB对尤状态会话EJB所做的任何方法调用都是RMI调用。 另个选择就是直接使用实体EJB的数据访问对象.以从数据库中检索必要的信息。 然而,这将会破坏由该实体EJB所实现的抽象,强迫它负责它不应该负责的东西.这已 经是另个对象的责任,最后,将会有一个会产生可维护性问题的代码副本。 解决方案就是把逻辑(也就是说确定是否批准锁定工作流模块定义的请求)放在无状 态会话EJB中。现在,实体EJB只知道如何维持和检索到达及来自数据库的请求。当检索 到锁定请求时,无状态会话EJB确定是否可以批准该请求,如果能.则命令实体EJB锁定 工作流模型定义。该解决方案维护了由对象所实现的抽象的完整性,并消除了不必要的EJB 间的关系。 分布式和分离操作。当设计组件以支持分布式和分离操作时.就会出现很多有趣的问 题,主要是关于是否支持工作流活动的分布式并发。考虑•个其工作流模型定义和运行时 实例位于多个服务器上的场景。尽管J2EE事务支持可以保证如果两个用户访问相同数据 库中的相同数据.他们不会违反工作流规则:但是,如果两个用户访问不同数据库中相同 工作流的复制数据.它就不能保证不会违反该规则。 在该场景中,一个用户可以将工作流模型定义锁定在•个位置,以对其进行修改.同 时,另外•个用户在另•个位置创建了相同定义的一个新的运行时实例。在分布式服务器 之间的数据复制和同步期间,可能会出现冲突,如果不解决的话,可能会破坏企业环境中 的工作流数据。为了保证在多个数据库间不违反工作流规则,需耍额外的功能来解决每种类型的冲突。实现这•级别的功能超出了Inmedius最初版本的范围。为了满足该需求,必 须支持分布式和详细的操作场景。 系统构架和环境规定了最初支持的分布式和分离操作的两个场景。在分布式操作中, 共享一个公共的存储库.它本身支持事务(例如数据库换句话说,应用服务器的多个 实例可能在几个位置,但每个实例都必须访问包含工作流模型定义和运行吋实例的相同的 数据存储库。这是因为应用服务器用来确定是否违反了工作流规则的信息存储在数据存储 库中。在分离操作中,-个安装(也就是应用服务器和数据存储库)被指定为主安装.所 有其他安装为从实例。必须通过主安装创建和设计工作流模型定义,然后将其复制到所有 从安装上。一旦定义成为分布式的,它就不能改变,除了指定谁可以参与已定义的活动。 因为从安装上的运行时工作流实例被创建并最后关闭,因此它们被复制回主安装中以支持 历史目的。 17.3.5使用J2EE的分支 本节讨论了关于J2EE使用的几个Luther决策的基本原理„ 1.根据设计做出的决策与由J2EE规定的决策 当使用J2EE运行时环境设计系统时.-些决策由设计人员做出,一些决策由J2EE规 则和结构限制。例如.J2EE规定了 servlet, JSP和EJB在容器中所驻留的位置——servlet 和JSP在Web层,EJB在EJB层- 然而,J2EE环境还为设计人员提供了一些灵活性一例如,往实现安全性(声明勻编程)、 亊务支持(声明与编程)和数据访问(容器管理的与bean管理的)时。 在设计组件时,设计人员对分配给servlet, JSP或EJB的功能具有总体控制,在这里, 显而易见的选择可能并不总是最好的。例如,丨nmedius的一个组件支持两个或多个用户之 间的协作。因为该组件代表可重用的业务逻辑,因此组件选择的规则指定应该将其打包为 EJB。遗憾的是,进-步的分析证明这并不是正确的设计。在确定如何将组件设计映射到 J2EE所提供的4个逻辑层上时,必须考虑额外的因素,如图16.2所示。 2. J2EE中的多层所引入的问题 一个问题是性能。导致性能差的一个主要因素就是从一个J2EE实体(如servlet, EJB) 到给定应用中的另-•个实体所进行的调用的数量。从技术角度说,每个EJB方法调用就是 个RMI调用.这可能是非常品贵的。粗粒度EJB的实现和实体间EJB关系的消除是解 决此问题的两个方法,因此确保了良好的组件性能。 另一个问题就是事务.可以通过由容器执行所有的授权检验来处理事务:也可以通过 在程序中进行授权检査来管理事务。很明显,第一个管理事务的方式耍稍微容易一些,因为代码没必要包含开始和结束的事务语句.然而.开发人员必须注意将如何使用其J2EE 实体。最容易的过程就是对所有的方法都要求事务。遗憾的是,如果并不真正需要事务. 则可能会产生不必要的运行时开销。当J2EE实体的方法不要求事务支持时就会出现另-个问题.部署描述符强迫进行执行。如果涉及事务的另一个容器使用J2EE实体,它创建 的事务将失敗。相反,部署描述符将声明该方法支持事务。必须仔细考虑组件的什么方法要求事务以确保正确的操作,必须将这些决策映射到J2EE支持的声明和编程机制的组合上。 17.4 Luther如何实现其质量目标 在Luther的所有质量需求中.除了一个需求外,其余所有需求都来自其客户:无线访问:灵活的用户接口和设备;支持现有的规程、业务过程和系统;支持分布式计箅、惟一一个来自Inmedius的需求是构建应用的轻松性。 实现这些需求的主要决策就是使用J2EE.但仅以一种特定的方式。用户接口淸晰干净地与应用分离幵,在任何可能的时候使用标准,抓住时机迅速构建一个可重用的组件库. 表17.1给出了该工作中使用的策略和战术。 17.5小 结 Inmedius为现场服务工人开发解决方案。此类工人要求很高的移动性,并能够不加限 制地访问计算机。这些计算机通常都具有很高的便携性,有时具有hands-free操作。在每 种情况下.系统都要求与后台操作集成在一起。 Luther是Inmedius构造用于支持客户支持系统的快速构建的解决方案,它基于J2EE。 我们已经投入大量的精力来幵发可重用的组件以及简化各部分功能添加的框架.而且其用 户接口设计用于支持基于客户和基于浏览器的解决方案。 采用J2EE促进了 Inmedius的商业目标.但同时也必须做出将什么打包为哪种bean的 额外的设计决策(或不打包为bean)。这是ABC的后向流的•个示例.它强调了从烟囱式 解决方案到公共解决方案的转变。 17.6可进一步参阅的文献 对可穿戴计箅机感兴趣的读者请参考[Barfield01],以及每年由IEEE主办的可穿戴计 算机国际研讨会的会议录( http://iswc.gatech.edu/)。 可以在fAlur 01]中找到在Luther构架中使用的业务委派模式。工作流管埋联盟在 http://www. wfmc.org 上报告 了 其活动。 17.7讨论题 (1)本书中的许多案例分析都采用了将系统中的数据生产者与数据使用者分离开来的 构架。为什么这样做非常重要?这使用的是哪种战术?编辑一个用于实现分离的战术或设 计方法列表,从本章所列的战术开始。 (2)在Luthei■构架和其他案例分析中.我们投入了大量的精力来关注将用户接口与应 用的其余部分分离开的问题,为什么此战术如此普及?