




已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一、序列图简介统一建模语言 (UML) 是用于建立面向对象系统模型的标准标记法。在 1995 到 1997 年之间,UML 登上了面向对象编程社区的舞台,而且在 1997 年后期受到了对象管理组织 (OMG) 的认可。虽然它最初颇受争议 - 因为它是在一片支持和反对声中提出的 - 但 UML 以后却成为系统标记法的行业标准。UML 的当前版本是 1.4,而且它将不断发展以满足面向对象开发人员的需要。UML 可能难以学习,主要因为它试图为相当广泛的情况提供建模标记法。每种建模标记法都采用一种图,而目前在 UML 规范中有九种图。幸好,学习 UML 可以是一个渐进过程;每次可以只学习一种图,首次试用时不必包含图中非常复杂的东西。在本专栏中,我将教您逐步学习基于 Java 应用程序开发的 UML 设计和标记法。我将以逻辑(可能是另人愉快的)方式介绍 UML 框架和其它建模技术的基础知识,您将通过建立现实示例的模型来学习实际操作。在第一部分中,我们使用贷款处理应用程序作为示例,从建立序列图开始。请注意,假设您熟悉 Java 语言,而且掌握了面向对象方法和术语的基础知识。本专栏将简要说明面向对象的概念,但不会进行深入讨论。关于序列图关于参与者角色参与者角色有助于发现和标识可以参与到用例方案中的参与者。一个参与者在一个用例和多个用例中可以有多个角色。目前,已经将四种不同的参与者角色标识成 UML 的增强或传统角色:启动程序、服务器、接收方和代理。因为可以在序列图中反映参与者角色,所以您应该熟悉它们的功能。 启动程序是设置行动中某个系统行为的外部实体。启动程序可以请求服务或生成事件。在显示参与者的序列图中,启动程序启动了行动中的序列。 外部 服务器角色为其它角色提供服务。服务器通过在外部提供功能或信息来帮助系统实现其目标。许多包含了操作系统的外部系统都是服务器角色。服务器会接收消息,但也许不会生成消息。接收方角色接收来自系统的信息。它们以消极方式提供服务。因此,它们可能不会向系统提供值,但会想其它参与者提供值。接收方的一个示例就是数据仓库或外部备份系统。接收方通常接收来自系统中对象的消息,但一般不会生成消息。 代理是代表另一个参与者执行操作的参与者。代理的一个示例就是代表顾客租借录影带的音像店职员。UML 没有排斥任何特殊的软件开发方法或过程;它只不过标准化了标记法的格式。然而,许多开发方法都合并了 UML。Rational 统一过程 (RUP) 就是这样一种方法;另一种方法是功能驱动的开发 (FDD)。由于其直观性和通用性,UML 序列图已成为这些过程的前端建模活动的一部分。序列图用于建立以下内容的模型:用例方案,框架中的协议,子系统,类,方法逻辑。以下是上述每个功能的简要说明。用例方案 对于示例应用程序,我们将使用序列图来建立单个用例方案的模型。用例是由参与者与应用程序交互为实现某个指定目标而执行的单个任务。参与者可以是与应用程序交互、在应用程序外部的任何最终用户、组织或系统。 框架中的协议 协议位于框架及其称作 集合体的可交换组件之间。了解框架必需的交互有助于开发新的集合体。序列图通常用于记录这些交互。 子系统 大的项目被分解成更小且易管理的部分,称作 子系统。子系统之间的接口关于将它们集成成为更大的整体(即,系统)是至关重要的。序列图用于指定子系统边界上的类之间的交互。 类 某些类(如 Socket 和 InetAddress )需要一个复杂的方法调用序列,以便正确交互。这些序列组成了用于与这样的某个类或一组类交互的协议。序列图可用于描述类或一组相互作用的类的使用,因而描述了交互所需的协议。方法逻辑 序列图在记录方法逻辑方面非常优秀。实际上,只要给出了 Java 方法,某些 CASE 工具会自动生成一个序列图。序列图可用于设计未来方法或记录现有方法的流程。 关于示例应用程序我们将在示例贷款处理应用程序的帮助下学习序列图。因为本专栏的重点在于建模,而不是方法,我们要直接讨论建立图,所以我们不会注重于应用程序的细节。我们为贷款处理应用程序绘制的基本功能如下:用例:提交贷款请求 申请人通过因特网完成并向银行提交贷款申请。系统确认贷款申请的信息,检查它是否正确以及信息是否尽可能完整。系统向外部商业资信咨询机构转发贷款请求,以获取该申请人的信用报告。系统根据所返回的信用报告计算申请人的信用积分。入门创建序列图的第一步是确定该图是否表示与外部或内部实体的交互。如果正在建立用例方案的模型,那么序列图通常表示与外部实体的交互。如果正在建立框架中协议的模型,那么此图也许表示内部或外部交互。子系统图、类图和个别方法逻辑图通常只表示内部实体。无论是哪种情况,将要建模的交互类型决定了序列图中的第一个(最左边的)元素。与外部实体的交互表示参与者是交互的一部分。内部交互可能由参与者启动(如果子系统用例是交互的基础),但它更可能是由叫作 Sender 的普通类启动的。如果参与者启动了交互,那么参与者将归入启动程序类别,这是四种常见参与者角色之一。 我们将关注为贷款处理应用程序(以上概述的 提交贷款请求用例)的方案建立图。请注意当申请人完成在线贷款申请并在因特网上提交它时序列图的变化。在这个方案中,申请人在系统外部,因此用参与者来表示他。我们首先将参与者 Applicant 添加到序列图,如图 1 所示。图 1. 添加申请人 添加参与者 一旦交互的启动程序就位,下一步就是添加它在方案的过程中将与之交互的对象。这些对象的名称应该反映出类或实例的行为。(类或实例的选择给出了与序列图截然不同的含义,但我将把这两者之间差异保留到下次讨论。) 对于示例方案,我们将添加两个类: LoanApplication 和 LoanRequest 。当申请贷款时,需要提交贷款申请。它包含了关于申请人和期望贷款金额的信息。贷款请求是银行向商业资信咨询机构发送的关于接受贷款申请的表单。它包含了来自贷款申请的一些信息,以及获取关于申请人的信用历史记录信息的请求。图 2 中显示了将这两个类添加到序列图中。 图 2. 添加两个交互类 连接各点 - 虚线 对于大多数软件开发人员来说,序列图是直观的。它们将对象和参与者(横轴)映射到时间(纵轴)。消息连接了对象,当消息发生时,它们沿着纵轴从一个对象移动到另一个对象。这些消息被连接到从对象或参与者底部的中间延伸出的竖直虚线。这条线被称作 生命线。 在横轴上,我们用被称作 调用箭头或 消息箭头的箭头来表示消息。消息箭头从发送方(尾)指向接收方(头)。这些箭头用于捕捉系统的动态行为。调用通常始于左边,向右边移动。即,交互中的初始箭头通常来自左边。当创建类的新实例时,我们绘制的箭头都指向类自身,而不是生命线。我们方案中的第一步是创建新的贷款申请,因此我们在 Applicant 和 LoanApplication 之间画出箭头。由于用 Java 创建新实例涉及到调用构造器,因此我们将这个箭头标上构造器名称,可能的话,还要标上变量。 我们仍处于软件开发生命周期中的分析阶段,因此我们要仅可能多地包含分析信息。我们的一个商务分析员提到我们把创建新贷款申请的操作称作“完成贷款申请”。如果我们要在构造过程中使这个序列图保持为真,那么可以将 complete 实现成公用方法,它将调用 LoanApplication 构造器,如图 3 所示。 图 3. 创建 LoanApplication 建立某个活动的图 但类或实例接收到消息时,它会在接收对象的生命线上创建一个框;这个框称作 活动。活动表示接收方的方法中的控制权流向。当消息导致创建了一个对象时,第一个活动表示构造器的逻辑。随后的消息将导致创建新的活动。 但接收到消息时,接收对象可以依次将消息发送到它自身或其它对象。这由箭头的尾巴显示,它表示箭头源于活动,而终止于新的活动。但对象调用自身时,新的活动将放到旧活动之上。在此方案中,申请人与贷款申请交互两次,第一次是完成它,而第二次是提交它。当 LoanApplication 接收到 submit 消息时,它会通过将 validate 消息发送到自身来验证它自己。如果有效,则它会创建要发送到商业资信咨询机构的新 LoanRequest 。图 4 显示了 LoanApplication 的验证过程。 图 4. 确认 LoanApplication 箭头文件:表示时间流逝 我们使用斜向箭头来表示消息发送和接收之间的真实时间的流逝。这种标记法用于显示非基本调用。非基本调用的示例是经由 CORBA 或 RMI 进行的方法调用,或是在网络上发送的消息。 在此示例中,商业资信咨询机构是一个外部系统,它是具有服务器角色的参与者。服务器通常不生成消息,但会有发送给它们的消息 - 在本例中是由信用检查器发送的信用报告的请求。信用检查器代表了商业资信咨询机构。它跟踪请求并将请求转发给商业资信咨询机构,跟踪并接收响应,此外就是建立贷款处理应用程序和商业资信咨询机构之间的连接。商业资信咨询机构将接收请求,并根据它自己的时间表处理请求。我们使用斜向箭头表示这段时间的流逝,如以下的图 5 所示。 在活动的结尾,返回到调用程序的结果是隐式的。然而,在某些情况下,您可能希望返回是显式的。显式返回调用由虚线箭头表示,该箭头的尾巴是接收方,头是发送方。显式返回箭头通常由调用返回的值标记。对于此示例,我们已经在 CreditBureau 和 CreditChecker 之间添加了显式箭头。这个箭头可以是带标签的 CreditReport ,因为它是从 requestCreditReport 方法返回的对象。 图 5. 获取 CreditReport 下一步 我在本文开头已经提到过,序列图用于描述系统运行时的内部行为。在本文中,我已经介绍了通过建立对象间交互的模型来构建序列图的第一步。在下一部分中,我将介绍两种序列图(常规和实例),并使用根据简单的 Java 方法绘制的示例说明条件逻辑在序列图中的角色。到时候见! 二、序列图中的条件逻辑我在介绍性专栏中曾经解释过,序列图用于描述系统随时间而产生的内部行为。因为系统行为是对象相互之间发送消息的结果,因此序列图绘制了那些消息在对象之间移动时的路线。归根结底,序列图就是交互图。在前一部分中,尽管我们描述了无数交互,但只创建了一个相当简单的图。这次,我们将做进一步的研究,看看 UML 指定的序列图的两种形态。这两种形态是 常规和 实例。让我们从每种形态的正确应用开始。 序列图的两种类型序列图用于描述对象之间两种不同类型的交互。一种交互类型是 必须 (must) 交互,其中对象 A 必须向对象 B 发送特定消息。另一种交互类型是 可能 (may) 交互,其中对象 A 可能(但不一定)向对象 B 发送特定消息。这两种形态的序列图描述了这两种不同类型的交互。常规形态描述的是 必须交互,而实例形态则描述了 可能交互。 常规形态的序列图描述初始刺激因素所产生的类交互。常规形态则记述了初始刺激因素能够产生的一切交互。成功和失败条件与循环、条件和分支一样,都是这种图的组成部分。常规序列图在水平轴方向上的每个框中只包含一个类名,如图 1 所示。它的含义是,交互背后的对象是匿名的,该类的任何对象都可以参与到交互中。因此,必须为所有路径明确建模。在常规序列图中,对象 A 必须向对象 B 发送模型中的一条消息。图 1. 常规序列图 序列图的第二种形态是实例形态。实例序列图描述了两个实例之间可能发生的单一消息交换。这样的图将在水平轴方向的框中包含一个变量名及其类类型,如图 2 所示。这种形态不包括常规形态中常见的循环、条件和分支。在系统中实际的控制流程中,在交互过程中所进行的某些断言可能为假。如果发现断言为假,实例序列图中的所有消息都为空,这种情形将不出现。实例序列图描述了可能发生也可能不发生的单一情形。图 2. 实例序列图 实例序列图最适合于在软件开发生命周期的分析阶段对个别方案建模。常规序列图可以为包含多个方案的整个用例建模。其它一些类型的活动 - 例如为子系统或框架与其各个部分之间使用的协议建模 - 可以使用任何一种形态,这取决于组件在软件开发生命周期中所处的位置。与实例形态相比,常规形态更接近于在最终产品中出现的实际代码。我们在前一专栏中使用的是常规形态,并将在此继续研究这种形态。这一次,我们将探究条件逻辑在常规序列图中所扮演的角色,通过它来让您了解有关 UML 表示的更多知识。序列图绘制中的条件逻辑常规序列图利用了条件逻辑,这对于描述交互过程中事件的可选流程来说很有用处。根据软件开发生命周期中所处的不同阶段,可以绘制详略度不同的图。在分析阶段,您可能愿意将详细信息排除在条件表达式以外,而在设计阶段,您却可能希望将最终产品中要使用的代码的片段包括在条件表达式中。无论处于开发周期中的哪个阶段,随着条件表达式图的绘制,序列图与如 Java 语言这样的面向对象语言之间那种自然的一致性就愈发清楚了。例如,请考虑一个允许出纳员接受存款的银行业务应用。除了其它一些事项以外,还规定了系统必须防止出纳员把负的金额记入帐户贷方,因为这会导致从帐户中扣除。因此系统必须有一种检查键入的所有金额均为正数的机制。清单 1 显示了确保存款为正数的条件表达式。清单 1. 带有条件表达式的方法*ThisisamethodinaTellerclass*public void receiveDeposit(Account account, BigDecimal deposit) throws ImproperDepositException /Checktoensurethedepositispositiveif(pareTo(new BigDecimal(0.0)0)account.credit(deposit); else throw new ImproperDepositException();在分析阶段,您不是很关心细节,因此图只需要表明存款为正数。在常规序列图中,条件作为带有消息名的保护机制出现,位于水平调用箭头上方。这些保护条件用方括号括起,放在消息名的左侧,如图 3 所示。图 3. 在分析期间添加的条件 上述方法和序列图之间的关系在图 4 中显现得更为清楚,我们在图 4 中看到了在设计阶段可能用到的更明确的图。当然没有显示全部方法:缺少了 else 子句。不过,图中消息箭头的语义规定只能在条件有效时发送消息。图 4. 更明确的条件 可以通过在 Teller 类和 ImproperDepositException 之间添加另一个调用箭头来为 else 子句建模。在这个调用上会有一个与 if 相反的条件;在本例中,即存款必须小于等于 0。您不妨自己尝试为这个语句建模。绘制 for 循环图 如上例所示,常规序列图 - 以及实际上所有 UML 图 - 几乎映射了 Java 语言的语法。所以,大多数 Java 开发者对这些图都有一个直观的理解,并且可以很快地学会如何使用它们。为进一步探讨常规序列图和 Java 语言之间的一致性,我们将绘制 for 循环图,如清单 2 所示。 清单 2. for 循环 for(inti=0;i4;i+)squareRoom.examineCorner(i);在序列图中,迭代是通过水平箭头上消息名之前的星号 (*) 来表示的。如果迭代的次数已知并且固定 - 这种情况非常少见 - 这个数字出现在星号后面的方括号中。因为大多数 for 循环处理的复杂逻辑不允许静态地确定迭代次数,因此您不会经常使用这种格式的括号表示。图 5 显示了上述 for 循环的序列图。 图 5. for 循环序列图 绘制 while 循环图 因为 while 循环将循环与条件结合起来,因此它是个非常容易接受的示例。我们将对清单 3 中显示的 while 循环绘制图。 清单 3. while 循环while(value.notFound()value=database.search(key);我们的 while 循环图既包含条件,又包含表明迭代的星号,但您会发现,没有迭代的次数。 while 循环很少包含迭代次数 - 除非它是一个伪装的 for 循环。图 6 显示了 while 循环图。 图 6. while 循环序列图 结束语一般来说, 必须和 可能行为是 UML 和软件开发的基本概念。用例捕捉 必须行为;方案捕捉 可能行为。类图捕捉 必须行为;实例图捕捉 可能行为。我主要讨论这一概念是因为我发现许多人没能掌握序列图的根本灵活性,而分化成直觉和形态使用这两个极端。 在阅读这些文章时,您应该把精力集中在发展模型语义的直观理解上。随着看到越来越多的序列图并开始创建自己的序列图,您会发现许多序列图依赖于条件逻辑和图表上下文来说明图所表示的是 必须还是 可能的系统视图。随着我们深入到更加复杂的图表绘制技术,及早学习如何识别和使用这种差别将对您今后有所帮助。 除了探讨序列图绘制中 必须和 可能行为的重要性以外,我还向您介绍了如何在图中表示条件和迭代。既然您已经知道如何绘制 for 和 while 循环图,我建议您在其它 Java 构造(例如 do-while 循环)上实践一下建模表示。随着您自己练习绘制这些简单构造图,自然会逐渐加深对序列图绘制的理解。三、用例模型需求收集是任何成功的软件开发周期中不可缺少的一步。虽然有众多的需求收集方法,但是最普通的方法是用例建模。在 先前的两个专栏中,我们已经完成了一部分将序列图同用例建模关联起来的工作。这次我将更多地谈论方法之后的理论,并且也增加一些您的建模词汇。 这次讨论中,我更关心的是阐明用户接口、系统接口和用例描述之间的关系。因为所建立的大多数系统将被设计成人机交互式的,所以将用例描述设计成以用户接口开始运行是很诱人的。但是在用例中包括用户接口逻辑通常被认为是不好的形式。这种说法的一个简单解释是,用户接口提供一个系统透视图的系统概貌。用例总是以参与者(或用户)透视图被描述。为了真正理解为什么我们在用例描述中不要包括 UI 逻辑,我们不得不采用亲身实践的方法。我们将使用第一个专栏中的贷款申请示例,并且您将看到用例是如何随着尺寸的增大而变得复杂。特别地,我们要注意在用例建模中透视图的角色。随着我们的深入,您将看到透视图是怎样被用来为您工作的,或者,如果被不正确地应用,它是如何阻碍您工作的。 什么是用例模型?一个用例模型由一张图表和一组阐明该用例的描述组成。一个用例是一个系统中的一组可能的交互,它的参与者朝着同一个被定义的目标进行。这些描述描述了系统中该用例的功能性;这张图表提供了这些描述的可视化路标。UML 规定了建立用例图表的标准,但并不是为了编写用例描述的。结果产生了许多编写用例描述的方法,这些方法有时是互相竞争的。最流行的编写用例描述的方法体现着 Ivar Jacobson (用例建模的发明者)的思想。Jacobson 的方法涉及一系列进入和退出的准则,分别被称作 前置条件和 后置条件,和一个称为 事件流的核心准则。这个事件流描述了一系列参与者(用户或外部系统)和被制定的系统之间的交互。这个事件流代表一个经过系统并通向成功输出的单一路径。这是用例描述的核心部分,但不是全部。事件流的交替和例外除描述中心事件流之外,用例描述必须说明那些发生在普通事件流之外的交互。例如录像带租用用例的主要事件流(在简单情况下)可以如下表示:录像带租赁店店员扫描顾客的会员卡。 系统取得会员名和他目前的租赁状况。一个“允许租赁”状态表示这个顾客可以租用录像带。 录像带租赁店店员扫描每盘被租借的录像带。 系统通过扫描每盘录像带,将可出租的录像带加入到用户可见的列表中,并显示当前的可出租的录像带列表。 录像带租赁店店员输入应收取的钱的数量(如果是现金)或者扫描信用卡。 系统标记这盘录像带为已在某段时间被出租并且打印这笔交易的收据。但是如果顾客在上次租借中欠了逾期费怎么办?在她能再次租借她所选的录像带之前,她需付清所欠的逾期费。逾期费的交互表现为一个 交替流或 例外流。事件流的交替和例外是很正常的。在某些情况下,他们可以被纠正以重新开始正常的事件流,在其他情况下,他们则达不到目标。在我们的示例中,如果顾客付了逾期费和这次的租金,那她就达到了继续租借录像带的目的了。 用例建模中的事务处理伴随着它的交替和例外,事件流是由一系列的事务处理组成。 事务处理是由参与者发起,并且当系统等候来自参与者的触发信号时完成的交互(注意完成事务处理的参与者不一定就是发起该事务处理的参与者)。事务处理允许我们把用例分割成更小的元素,并在每个决定点上将逻辑分组。 决定点是在描述中参与者必须作出决定或者提供额外信息的那个点。 所有的事务处理是由一个参与者和一个系统交互组成。您将极少需要计划一个没有启动的系统,即使这个启动仅仅以时间为基础。当建立用例模型的时候,您必须确保每个启动被某种类型的系统响应访问到。这个调用和响应对于用例来说是完整的。序列图中的事务处理事务处理在序列图中是很容易识别的。在我的第一个专栏中,我介绍了只有两个事务处理的方案。当申请者请求新的贷款申请时,第一个事务处理被启动。这个事务处理以系统等待申请者填写请求和提交请求为结束。当申请者在线提交了贷款申请时,第二个事务处理被启动。它以系统请求商业资信咨询机构的信用报告为结束。图 1 让我们再看一下建立用来描述这个方案的序列图 - 提交贷款请求和它的两个事务处理。这个图表建立了从开始到结束的两个事务处理的模型。您将会想起,这是一个一般的序列图,它允许我们在以后添加更多的方案(从而加入更多的事务处理)。至少就这个开发循环的分析阶段而言,当我们添加方案时,我们将完成这个用例。然而,当我们转向设计的时候,我们可能发现我们需要添加更多的事务处理。例如,如果我们选择作屏幕到屏幕的确认(代替当前在提交时的单一确认),我们必须在每一步确认时添加一个事务处理。现在看一下图 1,仔细注意事务处理的描述。以识别信息的方向从参与者到出现在最接近顶部的一个类或者实例为开始。正如您在下面的图表中看到,第一个事务处理通常是从左边开始。沿着箭头的顺序直到您到达了另外一个参与者或者顺序结束。当顺序结束时,它返回到最初的参与者。这就是一个事务处理。在图 1 中您应该能看到两个完整的事务处理。图 1. 一个提交贷款请求用例的部分序列图 象其他大多数用例那样,提交贷款请求用例使用多重的事务处理。迄今为止,我们只列出了其中的两个图表,但是一个普通的用例使用大约 3 到 15 个事务处理。为了理解透视图和事务处理的关系,我们可以看一下当两个系统通讯时事务处理是如何表现的。一些软件系统实际上是一系列互连的较小系统。这些较小系统相互合作提供整个系统的功能性。每个较小系统只提供整个系统功能的一个子集。他们通过一组协议和机器接口进行通讯,这将把我们的用例模型提高一个全新的复杂程度。互连系统的系统建模当考虑到互连系统时,这对建立由较小互连系统组成的大系统有意义。您可以交换一个系统并且用其它的系统替换它。您也可以独立地建立每一个系统。并且您可以用许多站点或厂商来完成整个系统。这样一个系统的最好示例是典型的电话网络。电话网络的一部分提供拨入通道,另一部分传送声音或数据,还有另一部分提供帐单服务,以及有许多其它部分开展象呼叫转移和语音邮件这样的服务。电话网络也许是由互连系统组成的系统的一个最大的示例,并且它的连续工作也证明了这种系统的有效性。同样的,懂得如何构思和建立这样的系统模型是十分重要的。一个相似的示例我们将使用一个相似的贷款处理申请来建立一个由互连系统组成的系统的模型。到现在,我们已经建立了提交贷款请求用例的模型,但是这个用例实际上只是一个较大的贷款处理系统的一部分。贷款提交系统和其进行交互的商业资信咨询机构是两个必须合作以提供必要的数据来处理贷款请求的系统。在现实生活中,还会涉及额外的系统。然而,我们的示例仅仅讨论两个系统。图 2 显示了两个系统、贷款提交和商业资信咨询机构系统以及我们将在这个专栏的余下部分着重讨论的交互。(注意,图 2 不是一个 UML 图表;它是一个真实世界的图表,目的是简单地图示这两个系统和它们之间的交互。)图 2. 两个系统之间的交互正如我们前面图表说明的那样,图 3 从贷款提交系统的透视图中显示了提交贷款请求用例的子集。这张图说明了我们第二次事务处理的结束是在申请者提交贷款请求时开始,在贷款提交系统 ( CreditChecker ) 给代表商业资信咨询机构 ( CreditBureau ) 的参与者发出请求时结束。 图 3. 一个提交贷款请求用例的系统部分的子集 现在,让我们注意来自于商业资信咨询机构系统的透视图的这个请求。我们将以代表请求一份信用报告的一个外部系统 ( CreditInstitution ) 的参与者开始。从商业资信咨询机构的透视图来看,当参与者请求报告时事务处理开始并且在商业资信咨询机构系统 ( CreditReporter ) 返回这个报告时结束,就如图 4 中的图表所示。 图 4. 商业资信咨询机构系统的一个序列图 回到贷款提交系统,我们现在能扩展提交贷款请求用例以包括报告的接收。当 CreditReporter 返回报告时,一个新的事务处理开始,并且报告被加入到与申请相联系的信息中。然后我们可以通知贷款官员(一个新的参与者)新的申请已到达。这将是我们的贷款提交方案中的第三个事务处理。为了创建整个用例,我们需要再加几个事务处理,但是我们将那个练习留到以后来做。 逆向透视图逻辑上面的图表说明了互连系统的系统建模中的两个重要方面。第一,从信息顺序透视图我们可以容易地将贷款提交和商业资信咨询机构系统作为单一的系统来进行建模。图 5 显示了这两个系统是如何在一个单一的图表中被建模成一个系统的。图 5. 一个单系统的信用报告功能视图 这项技术在我们开发循环的分析阶段中一直起作用。然而,当我们进入设计阶段时,两个系统中的通讯机制建模的必要性使得单一的图表过于复杂。除非我们使用一种象 CORBA 这样的通讯技术,否则我们一旦进入设计阶段,就必须分别为这两个系统建模。要分离它们,我们将插入一些参与者(就如图 3 和图 4 中所示)来分别互相代表两个系统。 第二个观察更加微妙,也是我们这周讨论的中心:我们能对这些服务形成一个概念上的理解,这些服务必须通过系统通过观察其它系统的需要来提供的。换句话说,我们可以通过查看其它系统的用例中的事务处理信息的子集来为每个系统确定概念上的接口。接着考虑贷款提交系统的第二和第三个事务处理。尤其得让我们查看第二个事务处理的 系统部分和第三个事务处理的 参与者部分。如果从概念上研究我们的商业资信咨询机构,参与者部分 ( CreditReporter ) 是贷款提交系统的系统部分的一个子集。也就是说,贷款提交系统用例表示“系统向商业资信咨询机构发送一个请求要求信用报告的一个副本。” 另一方面,商业资信咨询机构系统用例表示“这个信用机构参与者请求信用报告的一个副本。”这样,商业资信咨询机构事务处理的参与者部分是贷款提交系统的第二个事务处理的系统部分的一个子集。这对于第三个事务处理也是一样的,商业资信咨询机构事务处理的系统部分是第三个事务处理的参与者部分的一个子集。换句话说,事务处理的部分可以在两个系统间逆转。在两个系统间概念上的逆转事务处理提供了在两个互连系统间的概念上的粘合。例如,我们知道我们需要一个进入商业资信咨询机构的接口,以提供来自于贷款提交系统接口的信用报告,贷款提交系统接口同样请求这些报告。怎样把这个应用到用户接口我们并不是经常建立互连系统。然而,我们确实为我们所建立的大多数系统创建用户接口。我们通过逆转它们的用例事务处理将两个系统间的机器接口概念化。如果我们用一个用户接口替换一个机器接口,这也是对的。作为这篇文章的示例所显示的那样,我们为我们的系统所建立的用户接口将成为我们从相应的参与者透视图得出的用例描述的逆转。这就是为什么不能依靠用户接口透视图来编写出我们的用例。这儿的逻辑是创建概念上的用户接口,但是事务处理将不得不在应用之前被逆转。也就是说,如果您已经在编写基于 UI 的用例并能够以这种方法提供的话,那就坚持下去。您的提供能力比那些制定标准的头头们制定的标准远远重要。然而,如果使用这种方法陷入混乱,那么,您现在知道为什么了。下次我们将着眼于在灵活处理中捕获请求的不同机制,以及何时和为什么您应该使用那些特色、用户经历和在一个开发项目中的用例。下次见!四、参与者今天绝大多数计算机系统都处在某种网络之中。大多数系统除了为内部的用户群体服务,还要为该群体以外的实体提供某种价值或服务。作为回报,大多数系统也用了其它系统(例如,客户机端操作系统、Web 浏览器、外部数据库和第三方服务提供者)提供的服务。随着 Web 服务的到来,我们很快就会发现,我们开发的系统要为越来越广泛的应用程序提供服务。在 UML 工作簿系列的这一部分中,我们将来谈谈参与者在复杂系统的设计中的角色。为了便于讨论,我将介绍开发复杂系统时经常使用的两种设计模式,通过它们向您展示系统模型在从需求收集推进到分析和设计这个过程中的变化。这一部分通篇都将使用我们在 UML 工作簿系列的前几部分中开发的贷款申请用例。 为外部交互建模谈到为我们的系统和外部元素(如其它系统)之间的交互建模,通常的做法是,创建一些类,它们表示这些元素和我们的系统之间的交互方式。把外部实体表示为类,这样一种设计模式称为 镜像映象(Mirror Image)模式。当我们援用镜像映象模式时,我们基本上是先分析某一外部实体的的行为特征,然后在我们自己的系统中创建它的相似体。这个相似体通常很简单,因为它只是想抽象出我们需要的服务(对于单次使用这一情况)或系统提供的服务(对于诸如 Java 联网类类库这一情况)。它并不试图以任何方式实现这些服务。 我们通过研究 TCP/IP 在 Java SDK(包 )中的工作原理加以说明。TCP/IP 是大多数操作系统的基本功能。TCP/IP 是一个服务,它驻留在操作系统上,使流量得以跨网络流动。假如我们打算用 Java 代码写一个文件传输程序,我们可能要用到 Java 类库中的 TCP/IP 类,用它们来访问针对这个协议的操作系统服务。这些类将成为我们应用程序的一部分,但它们最终将驻留在操作系统中,而不是在应用程序中。 图 1是一张 UML 图,显示了一些表示 TCP/IP 服务的类,这些服务是针对 Java 联网类的。 这里重要的是要理解上图所示的类 表示了操作系统所提供的服务。它们并不是服务本身。我们之所以将这些表示纳入到我们的应用程序设计中,是因为它们使我们可以更容易地与操作系统交互。我们与这些表示交互,就 好像是在与服务本身交互一样。这些表示确保了交互被正确地传送至另一个系统,而且交互的任何结果都将按我们期望的方式返回。这就是 TCP/IP 类在 Java 类库中的角色。 识别外部交互识别与外部实体的交互在构建用例模型的需求收集阶段进行。在前面的专栏文章中,我们构建了一个用例模型, 参与者在其中表示与系统交互的外部实体。在 UML 工作簿系列的前一个专栏中,我们设计了一个既能与参与人(贷款申请人)又能与外部系统参与者(征信所)交互的系统。 图 2 显示了贷款处理系统最初的用例模型。 图 2. 贷款处理用例模型在我们最初概念化一个系统的时候,识别将影响系统的参与者是很重要的。理解了需求和服务在系统与其参与者之间的相互作用,我们就可以相应地分配系统资源。参与者在系统中的 角色决定了它对系统有多大程度的影响。 参与者的角色我们在 UML 工作簿系列的 第一篇文章中讨论了参与者可以扮演的各种角色。您或许能回想起来,参与者在用例中可能扮演四种角色:启动器(initiator)、服务器(server)、接收器(receiver)以及代理(facilitator)。如果某个参与者的作用是启动用例,则它的角色就是 启动器。如果参与者提供实现用例目标所需的一个或多个服务,那它充当的就是 服务器。当某个参与者的作用是接收来自系统的信息时,我们就称它为 接收器,数据仓库就是系统接收器的一个例子。最后,当某个参与者代表系统中的另一个参与者执行操作时,我们就称它为 代理。 参与者可以同时扮演多个角色。参与者可能是人或机器,其身份可以是匿名的,或者是已知的。如果参与者是匿名的,则它的身份对系统没有任何影响。最终用户在未曾标识的情况下可能会扮演多种角色;同样,不管是哪位最终用户扮演了某种角色 Tom、Mike 或是 Judy 他或她将经历完全相同的功能。机器也可能扮演匿名参与者,尤其是在 Web 服务领域中。相比而言,为了处理诸如安全或服务质量之类的事情,系统就需要标识信息了。在这样的情况下,参与者必须是已知的。任何时候当系统要求关于某个参与者的信息时 不管这个信息是确切的标识还是只鳞片爪的个别信息 这个参与者就被认为是一个已知的实体。从需求到实现当我们从用例图转入到序列图和类图时,马上就会注意到已知的参与者的影响。我们最初的序列图(在 UML 工作簿以前的部分中开发的)包含了已知的参与者。在这个层次的分析上,我们把系统与它的参与者之间的交互描述为一系列消息。因此,我们不是在处理个别的人或系统;相反地,我们把那些与系统交互的人或系统的细节封装到抽象的实体中,我们称它为参与者。图 3 图示了贷款申请用例的序列图的一部分。想查看完整的序列图,请参阅 UML 工作簿以前的部分。图 3. 贷款申请用例的序列图的一部分 当我们从序列图转到类图时,我们的系统分析就更精细了。因为在这个层次上,参与者是与需求和行为联系在一起,所以我们不再处理参与者的问题。相反,参与者背后的抽象概念可能将被提出来。在这个层次上出现的大多数“参与者”都将至少由一个属性标识;否则它们就是系统在分析阶段时所不感兴趣的参与者。任何级别的标识 哪怕只是一个属性 就能把一个参与者变成已知的参与者。而且,已知的参与者在类图中已不再是一个参与者;它成为了一个类。这个转变可能就像创建一个类来表示参与者那样简单,如图 4 所示。系统还可以将我们的参与者“看作”是更复杂的元素。在这个例子中,将会得到几种抽象。镜像映象模式的用武之地是后一种情况。镜像映象模式取得外部实体,然后将它转变成系统的一部分。在我们的贷款申请示例中,通过将已知的参与者转换成类而得到的类有两个。申请人和征信所都必须有标识性的特征。(如果我们的系统不要求这两个实体的标识性特征,那将为诈骗行为大开方便之门。)图 4. 一个利用了镜像映象模式的类图 在我们简单的模型中,存在一个参与者与所添加的类之间的一一映射。然而,参与者通常表示“更深层的”交互,可能产生多个类和更复杂的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026届福建省闽侯县第六中学化学高一上期中预测试题含解析
- 4.4并购防御战略
- 洋葱表皮细胞临时装片制作
- 医院火警应急预案体系构建
- 生殖医学中心病案室规范化管理
- 小班教研活动记录
- 呼吸机在新生儿科的临床运用
- 企业技术中心答辩
- 细胞工厂技术
- 心脏病处方讲解
- 养生茶基础知识培训课件
- 2025年暑假反电信网络诈骗试题及答案
- (完整版)中医适宜技术课件
- 机关、团体、企事业单位消防安全管理规定
- GB/T 20221-2023无压埋地排污、排水用硬聚氯乙烯(PVC-U)管材
- 等速肌力测试单关节或关节链不同运动模式以及运动角速度下的肌力参数
- 学生军训缓训(免训)申请表
- 真石漆施工工艺及要求【实用文档】doc
- 2017-2022年高考英语浙江卷七选五试题真题及答案汇编
- YB/T 117-1997高炉用耐火材料抗渣性试验方法
- GB/T 4744-2013纺织品防水性能的检测和评价静水压法
评论
0/150
提交评论