求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
 
Java 建模: UML 工作簿,第 4 部分――参与者的角色

2010-11-04 作者:Granville Miller 来源:IBM

 

为外部交互建模

谈到为我们的系统和外部元素(如其它系统)之间的交互建模,通常的做法是,创建一些类,它们表示这些元素和我们的系统之间的交互方式。把外部实体表示为类,这样一种设计模式称为 镜像映象(Mirror Image)模式。当我们援用镜像映象模式时,我们基本上是先分析某一外部实体的的行为特征,然后在我们自己的系统中创建它的相似体。这个相似体通常很简单,因为它只是想抽象出我们需要的服务(对于单次使用这一情况)或系统提供的服务(对于诸如 Java 联网类类库这一情况)。它并不试图以任何方式实现这些服务。

我们通过研究 TCP/IP 在 Java SDK(包 java.net )中的工作原理加以说明。TCP/IP 是大多数操作系统的基本功能。TCP/IP 是一个服务,它驻留在操作系统上,使流量得以跨网络流动。假如我们打算用 Java 代码写一个文件传输程序,我们可能要用到 Java 类库中的 TCP/IP 类,用它们来访问针对这个协议的操作系统服务。这些类将成为我们应用程序的一部分,但它们最终将驻留在操作系统中,而不是在应用程序中。

图 1是一张 UML 图,显示了一些表示 TCP/IP 服务的类,这些服务是针对 Java 联网类的。

这里重要的是要理解上图所示的类 表示了操作系统所提供的服务。它们并不是服务本身。我们之所以将这些表示纳入到我们的应用程序设计中,是因为它们使我们可以更容易地与操作系统交互。我们与这些表示交互,就 好像是在与服务本身交互一样。这些表示确保了交互被正确地传送至另一个系统,而且交互的任何结果都将按我们期望的方式返回。这就是 TCP/IP 类在 Java 类库中的角色。

识别外部交互

识别与外部实体的交互在构建用例模型的需求收集阶段进行。在前面的专栏文章中,我们构建了一个用例模型, 参与者在其中表示与系统交互的外部实体。在 UML 工作簿系列的前一个专栏中,我们设计了一个既能与参与人(贷款申请人)又能与外部系统参与者(征信所)交互的系统。

图 2 显示了贷款处理系统最初的用例模型。

图 2. 贷款处理用例模型

在我们最初概念化一个系统的时候,识别将影响系统的参与者是很重要的。理解了需求和服务在系统与其参与者之间的相互作用,我们就可以相应地分配系统资源。参与者在系统中的 角色决定了它对系统有多大程度的影响。

参与者的角色

我们在 前文中中讨论了参与者可以扮演的各种角色。您或许能回想起来,参与者在用例中可能扮演四种角色:启动器(initiator)、服务器(server)、接收器(receiver)以及代理(facilitator)。如果某个参与者的作用是启动用例,则它的角色就是 启动器。如果参与者提供实现用例目标所需的一个或多个服务,那它充当的就是 服务器。当某个参与者的作用是接收来自系统的信息时,我们就称它为 接收器,数据仓库就是系统接收器的一个例子。最后,当某个参与者代表系统中的另一个参与者执行操作时,我们就称它为 代理。

参与者可以同时扮演多个角色。参与者可能是人或机器,其身份可以是匿名的,或者是已知的。如果参与者是匿名的,则它的身份对系统没有任何影响。最终用户在未曾标识的情况下可能会扮演多种角色;同样,不管是哪位最终用户扮演了某种角色 ― Tom、Mike 或是 Judy ― 他或她将经历完全相同的功能。机器也可能扮演匿名参与者,尤其是在 Web 服务领域中。

相比而言,为了处理诸如安全或服务质量之类的事情,系统就需要标识信息了。在这样的情况下,参与者必须是已知的。任何时候当系统要求关于某个参与者的信息时 ― 不管这个信息是确切的标识还是只鳞片爪的个别信息 ― 这个参与者就被认为是一个已知的实体。

当我们从用例图转入到序列图和类图时,马上就会注意到已知的参与者的影响。我们最初的序列图(在 UML 工作簿以前的部分中开发的)包含了已知的参与者。在这个层次的分析上,我们把系统与它的参与者之间的交互描述为一系列消息。因此,我们不是在处理个别的人或系统;相反地,我们把那些与系统交互的人或系统的细节封装到抽象的实体中,我们称它为参与者。图 3 图示了贷款申请用例的序列图的一部分。想查看完整的序列图,请参阅 UML 工作簿以前的部分。

图 3. 贷款申请用例的序列图的一部分

当我们从序列图转到类图时,我们的系统分析就更精细了。因为在这个层次上,参与者是与需求和行为联系在一起,所以我们不再处理参与者的问题。相反,参与者背后的抽象概念可能将被提出来。在这个层次上出现的大多数“参与者”都将至少由一个属性标识;否则它们就是系统在分析阶段时所不感兴趣的参与者。任何级别的标识 ― 哪怕只是一个属性 ― 就能把一个参与者变成已知的参与者。而且,已知的参与者在类图中已不再是一个参与者;它成为了一个类。

这个转变可能就像创建一个类来表示参与者那样简单,如图 4 所示。系统还可以将我们的参与者“看作”是更复杂的元素。在这个例子中,将会得到几种抽象。镜像映象模式的用武之地是后一种情况。镜像映象模式取得外部实体,然后将它转变成系统的一部分。

在我们的贷款申请示例中,通过将已知的参与者转换成类而得到的类有两个。申请人和征信所都必须有标识性的特征。(如果我们的系统不要求这两个实体的标识性特征,那将为诈骗行为大开方便之门。)

图 4. 一个利用了镜像映象模式的类图

在我们简单的模型中,存在一个参与者与所添加的类之间的一一映射。然而,参与者通常表示“更深层的”交互,可能产生多个类和更复杂的交互。一个参与者可能需要添加许多类,而其中没有一个类使用了原始参与者的名称。

类图除表示已知的参与者之外,还常常表示服务器角色和接收器角色。这些角色可以是已知的或未知的,但为了系统能够使用由它们提供的服务,必须有一个或多个类来表示所提供的服务。通过 TCP/IP 示例,我们看到了这一点。

匿名参与者

诸如启动器或代理这样的匿名参与者也会使一些类被添加进来。但这种添加与设计而不是分析有关。我们注入这些类是由于与实际的系统实现有关的一些原因,而不是要反映业务约束。例如,我们可能会添加想与模型分离开来的用户接口逻辑,或者我们可能会出于性能方面的原因而添加某些类。

在 EJB 开发中, 会话虚包(Session Facade)模式常被用来使网络流量最小化和确保事务一致性。在 Web 服务的开发中,这一模式也有极重要的作用,该模式还是匿名参与者在系统设计中的用法的典型示例。会话虚包模式用对会话 bean 的单个调用来代替对实体 bean 的多个调用。新的会话 bean 代表客户机对服务器上的实体 bean 进行调用。

为了说明会话虚包模式,我们来考虑这样一个用例,用户能将贷款支付的帐目记入她的支票帐户的借方。如果我们用实体 bean 来实现这个付款用例,则一个简单的事务需要跨网络进行四个调用,如图 5 所示。此时您可能会回想起来,在序列图中,斜向箭头表明消息有较漫长的响应时间(这是跨网络发送消息而不是直接将消息发送到对象的结果)。此外,有可能其中某个事务永远也不会实际完成。

图 5 说明了实体 bean 将如何管理付款用例。

图 5. 用实体 bean 的办法来实现偿还贷款

对于我们的用例,单单实体 bean 显然不会是一种好的实现。性能就很成问题,而无法完成最后一个步骤(完成支付)可能会是一个更大的问题。通过在这个方案中加入一个会话 bean,会话虚包解决了这些问题。会话 bean 充当参与者的本地代理。

用会话 bean 进行建模

从逻辑上说,会话 bean 封装了它所代表的参与者所希望的操作。这样,会话 bean 就为我们与实体 bean 的交互提供了一个 虚包。会话 bean 让我们不用在网络间拖动数据几次,而是通过服务器上的一个事务就可以实现我们的目标。而且,注入会话 bean,就确保了用户事务的原子性,从而付款将被安全记入贷方。例如,会话 bean 会回滚无法完成的支付的任何借项。这就保证了我们用户的钱不会凭空消失。

会话 bean 还能代表参与者进行多种操作。会话 bean 的行为与参与者在用例模型内汇集起来的行为一致。因此,如果一个申请人参与者发起了一个申请贷款用例和一个接受贷款用例,则这两个用例的工作流将被收集到申请人会话 bean 中。申请人会话 bean 可以申请一项贷款,然后在另一个事务中接受它。

图 6 说明了引入会话 bean 给我们的付款用例带来的变化。

图 6. 用会话虚包的办法实现付款

正如我们已经看到的,会话 bean 被指定给某个参与者,利用它对该参与者的特有了解,会话 bean 既方便了参与者的事务又增强了系统性能。会话虚包模式可用于已知的和未知的参与者。这种模式不太用于服务器角色和接收器角色的参与者。它更多是为了启动器或代理角色的参与者而被实现。显然,付款用例中的客户是启动器角色。

结束语

对于将用例图中的参与者转换成类图中有效的抽象,镜像映象模式和会话虚包模式是很有用的,这样最终将能够更清楚地转换成代码。已知的参与者通常在系统的逻辑中能有某种形式的体现;匿名参与者也一样。

从图到代码的转换,其更重要的含义是 可跟踪性。通过使用诸如镜像映象和会话虚包之类的模式,我们就可以跟踪类的创建过程,以反映出外部实体的标识或它所提供的服务。我们可以通过其逆过程理解使这些类得以产生的元素。这些转换的目标是使抽象更好,代码更易于理解和维护。



Java 中的中文编码问题
Java基础知识的三十个经典问答
玩转 Java Web 应用开发
使用Spring更好地处理Struts
用Eclipse开发iPhone Web应用
插件系统框架分析
更多...   


Struts+Spring+Hibernate
基于J2EE的Web 2.0应用开发
J2EE设计模式和性能调优
Java EE 5企业级架构设计
Java单元测试方法与技术
Java编程方法与技术


Struts+Spring+Hibernate/EJB+性能优化
华夏基金 ActiveMQ 原理与管理
某民航公司 Java基础编程到应用开发
某风电公司 Java 应用开发平台与迁移
日照港 J2EE应用开发技术框架与实践
某跨国公司 工作流管理JBPM
东方航空公司 高级J2EE及其前沿技术
更多...