序列图主要用于按照交互发生的一系列顺序,显示对象之间的这些交互。很象类图,开发者一般认为序列图只对他们有意义。然而,一个组织的业务人员会发现,序列图显示不同的业务对象如何交互,对于交流当前业务如何进行很有用。除记录组织的当前事件外,一个业务级的序列图能被当作一个需求文件使用,为实现一个未来系统传递需求。在项目的需求阶段,分析师能通过提供一个更加正式层次的表达,把用例带入下一层次。那种情况下,用例常常被细化为一个或者更多的序列图。
组织的技术人员能发现,序列图在记录一个未来系统的行为应该如何表现中,非常有用。在设计阶段,架构师和开发者能使用图,挖掘出系统对象间的交互,这样充实整个系统设计。
序列图的主要用途之一,是把用例表达的需求,转化为进一步、更加正式层次的精细表达。用例常常被细化为一个或者更多的序列图。序列图除了在设计新系统方面的用途外,它们还能用来记录一个存在系统(称它为“遗产”)的对象现在如何交互。当把这个系统移交给另一个人或组织时,这个文档很有用。
序列图的主要目的是定义事件序列,产生一些希望的输出。重点不是消息本身,而是消息产生的顺序;不过,大多数序列图会表示一个系统的对象之间传递的什么消息,以及它们发生的顺序。图按照水平和垂直的维度传递信息:垂直维度从上而下表示消息/调用发生的时间序列,而且水平维度从左到右表示消息发送到的对象实例。
生命线
当画一个序列图的时候,放置生命线符号元件,横跨图的顶部。生命线表示序列中,建模的角色或对象实例。 生命线画作一个方格,一条虚线从上而下,通过底部边界的中心(图 3)。生命线名字放置在方格里。
图 3: 用于一个实体名为freshman的生命线的Student类的一个例子
UML 的生命线命名标准按照如下格式:
在如图3所示的例子中,生命线表示类Student的实体,它的实体名称是freshman。这里注意一点,生命线名称带下划线。当使用下划线时,意味着序列图中的生命线代表一个类的特定实体,不是特定种类的实体(例如,角色)。在将来的一篇文章中,我们将会了解结构化建模。现在,仅仅评述序列图,可能包含角色(例如买方和卖方),而不需要叙述谁扮演那些角色(例如Bill和Fred)。这准许不同语境的图重复使用。简单拖放,序列图的实例名称有下划线,而角色名称没有。
图 3 中我们生命线例子是一个命名的对象,但是不是所有的生命线都代表命名的对象。相反的,一个生命线能用来表现一个匿名的或未命名的实体。当在一个序列图上,为一个未命名的实例建模时,生命线的名字采用和一个命名实例相同的模式;但是生命线名字的位置留下空白,而不是提供一个例图名字。再次参考图 3,如果生命线正在表现Student类的一个匿名例图,生命线会是: “Student”。同时, 因为序列图在项目设计阶段中使用,有一个未指定的对象是完全合法: 举例来说,“freshman”。
消息
为了可读性,序列图的第一个消息总是从顶端开始,并且一般位于图的左边。然后继发的消息加入图中,稍微比前面的消息低些。
为了显示一个对象(例如,生命线)传递一个消息给另外一个对象,你画一条线指向接收对象,包括一个实心箭头(如果是一个同步调用操作)或一个棍形箭头(如果是一个异步讯号)。消息/方法名字放置在带箭头的线上面。正在被传递给接收对象的消息,表示接收对象的类实现的一个操作/方法。在图 4 的例子中,analyst对象调用ReportingSystem 类的一个实例的系统对象。analyst对象在调用系统对象的 getAvailableReports 方法。系统对象然后调用secSystem 对象上的、包括参数userId的getSecurityClearance 方法,secSystem的类的类型是 SecuritySystem。
图 4: 一个在对象之间传递消息的实例
除了仅仅显示序列图上的消息调用外,图 4 中的图还包括返回消息。这些返回消息是可选择的;一个返回消息画作一个带开放箭头的虚线,向后指向来源的生命线,在这条虚线上面,你放置操作的返回值。在图 4 中,当 getSecurityClearance 方法被调用时,secSystem 对象返回 userClearance 给系统对象。当 getAvailableReports 方法被调用时,系统对象返回 availableReports。
此外,返回消息是序列图的一个可选择部分。返回消息的使用依赖建模的具体/抽象程度。如果需要较好的具体化,返回消息是有用的;否则,主动消息就足够了。我个人喜欢,无论什么时候返回一个值,都包括一个返回消息,因为我发现额外的细节使一个序列图变得更容易阅读。
当序列图建模时,有时候,一个对象将会需要传递一个消息给它本身。一个对象何时称它本身?一个纯化论者会争辩一个对象应该永不传递一个消息给它本身。然而,为传递一个消息给它本身的对象建模,在一些情境中可能是有用的。举例来说,图 5 是图 4 的一个改良版本。 图 5 版本显示调用它的 determineAvailableReports 方法的系统对象。通过表示系统传递消息“determineAvailableReports”给它本身,模型把注意力集中到过程的事实上,而不是系统对象。
为了要画一个调用本身的对象,如你平时所作的,画一条消息,但是不是连接它到另外的一个对象,而是你把消息连接回对象本身。
图 5: 系统对象调用它的 determineAvailableReports 方法
图 5 中的消息实例显示同步消息;然而,在序列图中,你也能为异步消息建模。一个异步消息和一个同步的画法类似,但是消息画的线带一个棍形矛头,如图 6 所示。
图 6: 表示传递到实体2的异步消息的序列图片段
约束
当为对象的交互建模时,有时候,必须满足一个条件,消息才会传递给对象。约束在 UML 图各处中,用于控制流。在这里,我将会讨论UML 1.x 及UML 2.0两者的约束。在 UML 1.x 中,一个约束只可能被分配到一个单一消息。UML 1.x中,为了在一个序列图上画一个约束,你把约束元件放在约束的消息线上,消息名字之前。图 7 显示序列图的一个片段,消息addStudent 方法上有一个约束。
图 7:UML 1.x 序列图的一个片段,其中addStudent 消息有一个约束
在图 7 中,约束是文本“[ pastDueBalance=0]”。通过这个消息上的约束,如果应收帐系统返回一个零点的逾期平衡,addStudent 消息才将会被传递。约束的符号很简单;格式是:
举例来说,
组合碎片(变体方案,选择项,和循环)
然而,在大多数的序列图中,UML 1.x“in-line”约束不足以处理一个建模序列的必需逻辑。这个功能缺失是 UML 1.x 的一个问题。UML 2 已经通过去掉“in-line”约束,增加一个叫做组合碎片的符号元件,解决了这一个问题。一个组合碎片用来把一套消息组合在一起,在一个序列图中显示条件分支。UML 2 规范指明了组合碎片的 11 种交互类型。十一种中的三种将会在“基础”段落中介绍,另外两种类型将会在“超越基础”中介绍,而那剩余的六种我将会留在另一篇文章中介绍。(嗨,这是一篇文章而不是一本书。我希望你在一天中看完这部分!)
变体
变体用来指明在两个或更多的消息序列之间的、互斥的选择。 变体支持经典的“if then else”逻辑的建模(举例来说,如果 我买三个,然后 我得到 我购买的20% 折扣;否则 我得到我购买的 10% 折扣)。
就如你将会在图 8 中注意到的,一个变体的组合碎片元件使用框架来画。单词“alt”放置在框架的namebox里。然后较大的长方形分为 UML 2 所称的操作元。 操作元被虚线分开。每个操作元有一个约束进行测试,而这个约束被放置在生命线顶端的操作元的左上部。 如果操作元的约束等于“true”,然后那个操作元是要执行的操作元。
图 8:包含变体组合碎片的一个序列图片段
图 8作为一个变体的组合碎片如何阅读的例子,显示序列从顶部开始,即bank对象获取支票金额和帐户结余。此时,序列图中的变体组合碎片接管。因为约束“[balance >= amount]”,如果余额超过或等于金额,然后顺序进行bank对象传递 addDebitTransaction 和 storePhotoOfCheck 消息给account对象。然而,如果余额不是超过或等于金额,然后顺序的过程就是bank传递addInsuffientFundFee 和 noteReturnedCheck 消息给account对象,returnCheck 消息给它自身。因为“else”约束,当余额不大于或者等于金额时,第二个序列被调用。在变体的组合碎片中,不需要“else”约束;而如果一个操作元,在它上面没有一个明确的约束,那么将假定“else”约束。
变体的组合碎片没被限制在简单的“if then else”验证。可能需要大量的变体路径。 如果需要较多的变体方案,你一定要做的全部工作就是把一个操作元加入有序列约束和消息的长方形中。
选择项
选择项组合碎片用来为序列建模,这些序列给予一个特定条件,将会发生的;或者,序列不发生。一个选择项用来为简单的“if then”表达式建模。(例如,如果架上的圈饼少于五个,那么另外做两打圈饼)。
选择项组合碎片符号与变体组合碎片类似,除了它只有一个操作元并且永不能有“else”约束以外(它就是如此,没有理由)。要画选择项组合,你画一个框架。文字“opt”是被放置在框架的 namebox 里的文本,在框架的内容区,选择项的约束被放置在生命线顶端上的左上角。 然后选择项的消息序列被放在框架的内容区的其余位置内。这些元件如图 9 所示。
图 9:包括选择项组合碎片的一个序列图片段
阅读选择项组合碎片很容易。图 9 是图 7 的序列图片段的再加工,但是这次它使用一个选择项组合碎片,因为如果Student的逾期平衡等于0,需要传递更多的消息。按照图 9 的序列图,如果Student的逾期平衡等于零,然后传递addStudent,getCostOfClass和chargeForClass消息。如果Student的逾期平衡不等于零,那么在选择项组合碎片中,序列不传递任何一个消息。
例子图 9的序列图片段包括一个选择项约束;然而,约束不是一个必需的元件。在高层次、抽象的序列图中,你可能不想叙述选择项的条件。你可能只是想要指出片段是可选择的。
循环
有时候你将会需要为一个重复的序列建模。在 UML 2 中,为一个重复的序列建模已经改良,附加了循环组合碎片。
循环组合碎片表面非常类似选择项组合碎片。你画一个框架,在框架的 namebox 中放置文本“loop”。在框架的内容区中,一个生命线的顶部,循环约束 被放置在左上角。然后循环的消息序列被放在框架内容区的其余部分中。在一个循环中,除了标准的布尔测试外,一个约束能测试二个特定的条件式。特定的约束条件式是写作“minint = [the number]”(例如,“minint = 1”)的最小循环次数,和写作“maxint = [the number]”(例如,“maxint = 5”)的最大循环次数。通过最小循环检验,循环必须运行至少指定次数,而循环执行次数不能达到约束指定的最大循环次数。
图 10:循环组合碎片的一个序列图例子
引用另外一个序列图
当做序列图的时候,开发者爱在他们的序列图中,重用存在的序列图。 7 在 UML 2 中开始,引进“交互进行”元件。追加交互进行的可以说是 UML 2 交互建模中的最重要的创新。交互进行增加了功能,把原始的序列图组织成为复杂的序列图。由于这些,你能组合(重用)较简单的序列,生成比较复杂的序列。这意味你能把完整的、可能比较复杂的序列,抽象为一个单一的概念单位。
一个交互进行元件使用一个框架绘制。文字“ref”放置在框架的 namebox 中,引用的序列图名字放置在框架的内容区里,连同序列图的任何参数一起。引用序列图的名字符号如下模式:
两个例子:
1. Retrieve Borrower Credit Report(ssn) : borrowerCreditReport
或者
2. Process Credit Card(name, number, expirationDate, amount : 100)
在例子 1 中,语法调用叫做Retrieve Borrower Credit Report的序列图,传递给它参数 ssn。序列Retreive Borrower Credit Report返回变量 borrowerCreditReport 。
在实例 2 中,语法调用叫做Process Credit Card的序列图,传递给它参数name,number,expiration date,和 amount。然而,在例子 2 中,amount参数将会是值100。因为例子2没有返回值标签,序列不返回值(假设,建模的序列不需要返回值)。
图 11: 一个引用两个不同序列图的序列图
图 11 显示一个序列图,它引用了序列图“Balance Lookup”和“Debit Account”。序列从左上角开始,客户传递一个消息给teller对象。teller对象传递一个消息给 theirBank 对象。那时,调用Balance Lookup序列图,而 accountNumber作为一个参数传递。Balance Lookup序列图返回balance变量。然后检验选择项组合碎片的约束条件,确认余额大于金额变量。在余额比金额更大的情况下,调用Debit Account序列图,给它传递参数accountNumber 和amount。在那个序列完成后,withdrawCash 消息为客户返回cash。
重要的是,注意在图 11 中,theirBank 的生命线被交互进行Balance Lookup隐藏了。因为交互进行隐藏生命线,意味着theirBank 生命线在“Balance Lookup”序列图中被引用。除了隐藏交互进行的生命线之外,UML 2 也指明,生命线在它自己的“Balance Lookup”序列中,一定有相同的 theirBank 。
有时候,你为一个序列图建模,其中交互进行会重叠没有 在交互进行中引用的生命线。在那种情况下,生命线和正常的生命线一样显示,不会被重叠的交互进行隐藏。
在图 11 中,序列引用“Balance Lookup”序列图。“Balance Lookup”序列图在图 12 中显示。因为例子序列有参数和一个返回值,它的标签 —— 位于图的 namebox 中 —— 按照一个特定模式:
两个例子:
1. SD Balance Lookup(Integer : accountNumber) : Real
或
2. SD Available Reports(Financial Analyst : analyst) : Reports
图 12 举例说明例子 1,在里面,Balance Lookup序列把参数 accountNumber 作为序列中的变量使用,序列图显示返回的Real对象。在类似这种情况下,返回的对象采用序列图实体名。
图 12: 一个使用 accountNumber 参数并返回一个Real对象的序列图
图 13 举例说明例子 2,在里面,一个序列图获取一个参数,返回一个对象。然而,在图 13 中参数在序列的交互中使用
图 13: 一个在它的交互中使用参数、返回一个Reports对象的序列图
门
前面的段落展示如何通过参数和返回值传递信息,引用另一个序列图。然而,有另一个方法在序列图之间传递消息。门可能是一个容易的方法,为在序列图和它的上下文之间的传递消息建模。一个门只是一个消息,图形表示为一端连接序列图的框架边缘,另一端连接到生命线。使用门的图 11 和 12 ,在图 14 和 15 中可以被看到重构。图 15 的例图有一个叫做getBalance的入口门,获取参数 accountNumber。因为是箭头的线连接到图的框架,而箭头连接到生命线,所以 getBalance 消息是一个入口门。序列图也有一个出囗门,返回balance变量。出口门同理可知,因为它是一个返回消息,连接从一个生命线到图的框架,箭头连接框架。
图 14: 图 11 的重构,这次使用门
图 15: 图 12 的重构,这次使用门
组合碎片(跳转和并行)
在本文前面“基础”的段落中呈现的,我介绍了“变体”,“选择项”,和“循环”的组合碎片。这些三个组合碎片是大多数人将会使用最多的。然而,有二个其他的组合碎片,大量共享的人将会发现有用——跳转和并行。
跳转
跳转组合碎片几乎在每个方面都和选择项组合碎片一致,除了两个例外。首先,跳转的框架namebox的文本“break”代替了“option”。其次, 当一个跳转组合碎片的消息运行时,封闭的交互作用的其他消息将不会执行,因为序列打破了封闭的交互。这样,跳转组合碎片非常象 C++ 或 Java 的编程语言中的break关键字。
图 16: 来自图 8 的序列图片段的重构,片段使用跳转代替变体
跳转最常用来做模型异常处理。图 16 是图 8 的重构,但是这次图16使用跳转组合碎片,因为它把balance < amount的情况作为一个异常对待,而不是一个变体流。要阅读图 16,你从序列的左上角开始,向下读。当序列到达返回值“balance”的时候,它检查看看是否余额比金额更少。如果余额不少于金额,被传递的下一个消息是 addDebitTransaction 消息,而且序列正常继续。然而,在余额比金额更少的情况下,然后序列进入跳转组合碎片,它的消息被传递。一旦跳转组合的消息的已经被传递,序列不发送任何其它消息就退出(举例来说,addDebitTransaction)。
注意有关跳转的一件重要的事是,它们只引起一个封闭交互的序列退出,不必完成图中描述的序列。在这种情况下,跳转组合是变体或者循环的一部分,然后只是变体或循环被退出。
并行
今天的现代计算机系统在复杂性和有时执行并发任务方面不断进步。当完成一个复杂任务需要的处理时间比希望的长的时候,一些系统采用并行处理进程的各部分。当创造一个序列图,显示并行处理活动的时候,需要使用并行组合碎片元件。
并行组合碎片使用一个框架来画,你把文本“par”放在框架的 namebox 中。然后你把框架的内容段用虚线分为水平操作元。框架的每个操作元表示一个在并行运行的线程。
图 17: oven 是并行做两个任务的对象实例
图 17 可能没有举例说明做并行活动的对象的最好的计算机系统实例,不过提供了一个容易理解的并行活动序列的例子。序列如这样进行:hungryPerson 传递 cookFood 消息给oven 对象。当oven 对象接收那个消息时,它同时发送两个消息(nukeFood 和 rotateFood)给它本身。这些消息都处理后,hungryPerson 对象从oven 对象返回 yummyFood 。
分享到:
相关推荐
在此过程中,UML(统一建模语言)起到了至关重要的作用,尤其是其行为图,包括序列图和协作图,为设计者提供了一种强大的工具来可视化系统行为。 UML网购系统中,序列图专注于展示系统中对象间的交互顺序。以“游客...
序列图有助于理解系统中各个对象如何协同工作以完成特定的任务或业务流程,特别适合用于设计阶段和文档编写过程中,帮助团队成员更好地理解系统的交互逻辑。 #### 总结 UML作为一种重要的建模语言,提供了丰富的...
序列图的主要目的是展示对象间的交互逻辑,并且按照时间顺序呈现这些交互。它既可以用于开发人员理解和实现系统对象之间的交互,也可以帮助业务人员描述不同业务对象如何相互作用。具体来说: 1. **开发人员角度**...
最后,文章强调了可视化交互技术在信息可视化中的重要性,并提出了基于地图的交互式可视化空间查询与空间分析的基本框架。这个框架将为理解和开发更高级的交互式空间可视化应用提供理论基础和实践指导,对于地理信息...
序列图强调了对象间消息传递的时间顺序,并描述了对象如何在特定的场景下交互。 在原有的序列图逆向生成方法中,通常需要对源代码进行动态分析,然后根据分析结果构建序列图。这个过程中包含复杂的迭代判断,即检查...
在IT行业中,理解和设计软件系统的架构至关重要,而序列图和ER图则是两种非常重要的建模工具。本文将深入探讨jforum论坛系统中的序列图和ER图,帮助读者了解其设计理念和实现机制。 首先,让我们来看看jforum。...
开发人员通常会利用序列图来梳理系统中各个对象之间的交互逻辑,尤其是对于那些并发处理或事务处理的复杂场景。通过序列图,设计者可以理解在特定操作序列中,对象之间是如何进行沟通的,哪些对象是主动的参与者,...
在Android系统中,序列图可以用来描述服务间的通信、用户界面与后台进程的交互等复杂流程。它们是理解系统动态行为的重要工具,帮助开发者理清各组件间的调用关系。 在实际应用中,Android系统源代码的情景分析可能...
通过这个毕业设计,我们可以学习到Java游戏开发的实践知识,同时也可以了解到理论与实际结合的重要性。无论你是初学者还是经验丰富的开发者,这份资源都能提供宝贵的学习材料,帮助你提升在Java游戏设计领域的技能。
在当今数字化时代,家教服务的需求日益增长,而家教发布系统作为连接学生家长和教师的桥梁,其重要性不言而喻。为了构建一个高效、易用的在线平台,软件开发团队通常会借助UML(统一建模语言)来进行系统设计。UML...
服务设计作为一种方法论,在交互界面设计中占据着核心地位,它提倡以用户为中心,通过共同创造、逻辑化服务流程、证据展示及全局思考来完善用户体验。 服务设计的五大要点是设计者在调研分析过程中必须关注的核心...
2. 过程建模:采用活动图或序列图来描述用户与系统的交互流程,如用户搜索商品、添加购物车、支付订单等操作的步骤。 3. 面向对象分析:利用类图描述系统中的类及其相互关系,包括属性、方法和继承等。 四、物理...
这份文档包含了丰富的图表,如类图、流程图、时序图、序列图和活动图,这些都是软件工程中用于理解和描述系统功能与交互的重要工具。 1. **类图(Class Diagram)**:在面向对象编程中,类图是UML(统一建模语言)的...
1. 引言:介绍研究背景、目的和UML的重要性,简述论文的主要内容。 2. UML基础:简述UML的基本概念和主要图表类型,为后续分析奠定基础。 3. 项目概述:描述项目背景、目标和需求,明确要解决的问题。 4. UML建模:...
文章强调了数据结构在图形系统中的重要性,指出交互式图形系统区别于被动式图形系统的一个主要特点是能够对已绘制的实体进行编辑。因此,合适的图形数据结构对于系统的内存空间利用率、运行效率、可靠性和易维护性...
目前,大多数3D交互动画依赖于预设的动画序列,而未来的发展方向则是在保持画面流畅的基础上,实现更高质量的光影效果,这将成为3D交互技术的一大突破点。 ### 个性化和创新性设计趋势 随着市场对个性化和创新性的...
3. **动态面板与交互逻辑**:通过动态面板,设计者可以创建复杂的页面状态变化和过渡动画,模拟真实应用的交互效果。而交互逻辑则允许设计者设定事件触发条件,如鼠标点击、滑动等,进一步增强了原型的真实感。 4. ...
这一方法旨在利用GPS数据和全景序列图像来自动创建游戏环境中的路口网络,提高游戏地图的真实感和交互性。 在网络游戏开发中,构建真实世界的虚拟地图是一项重要的任务。传统的做法通常是人工设计,这既耗时又费力...
接着,为每个用例绘制顺序图,重点描绘对象之间的交互逻辑和控制流程。对于复杂的交互场景,可以辅助以协作图来补充说明对象之间的静态连接关系,增强模型的完整性。 #### 实战案例分析 以“新增书籍信息”用例为...