8.1 概述
对象间的相互作用体现了对象的行为。这种相互作用可以描述成两种互补的方式,一种以独立的对象为中心进行考察,另一种以互相作用的一组对象为中心进行考察。
状态机的描述范围不宽,但它描述了对象深层次的行为,是单独考察每一个对象的“微缩”视图。对状态机的说明是精确的并且可直接用于代码。然而,在理解系统的整个功能时存在困难,因为状态机一个时刻只集中描述一个对象,要确定整个系统的行为必需同时结合多个状态机进行考察。交互视图更适合于描述一组对象的整体行为。交互视图是对象间协作关系的模型。
8.2 协作
协作描述了在一定的语境中一组对象以及用以实现某些行为的这些对象间的相互作用。它描述了为实现某种目的而相互合作的“对象社会”。协作中有在运行时被对象和连接占用的槽。协作槽也叫做角色,因为它描述了协作中的对象或连接的目的。类元角色表示参与协作执行的对象的描述;关联角色表示参与协作执行的关联的描述。类元角色是在协作中被部分约束的类元;关联角色是在协作中被部分约束的关联。协作中的类元角色与关联角色之间的关系只在特定的语境中才有意义。通常,同样的关系不适用于协作外的潜在的类元和关联。
静态视图描述了类固有的内在属性。例如,Vehicle 需要有一个所有者。协作图描述了类实例的特性,因为它在协作中起特殊的作用,例如,在一个RentalCar的协作中,rentalVehicle 需要 rentalDriver,它通常与交通工具不直接相关但它是协作的基本部分。
系统中的对象可以参与一个或多个协作。虽然协作的执行通过共享对象相连,但是对象所出现的协作不必直接相关。例如,在一个Vacation模型中,某人可以既是rental Driver同时又是hotelGuest。不经常出现的情况是一个对象在同一个协作中可能担当多个角色。
合作包括结构和行为两个方面。结构方面与静态视图相似—包含一个角色集合和它们之间的关系,这些关系定义了行为方面的内容。行为方面是一个消息集合,这些消息在具有某一角色的各对象间进行传递交换。协作中的消息集合叫做交互。一个协作可以包含一个或多个交互,每个交互描述了一系列消息,协作中的对象为了达到目标交换这些消息。
状态机描述范围具有一定的局限性,但它的描述层次较深入,协作不受限制但描述层次较浅。它捕获了对象组成的网络结构中相互发送消息的整体行为。协作表示潜藏于计算过程中的三个主要结构的统一,即数据结构、控制流和数据流的统一。
8.3 交互
交互是协作中的一个消息集合,这些消息被类元角色通过关联角色交换。当协作在运行时,受类元角色约束的对象通过受关联角色约束的连接交换消息实例。交互作用可对操作的执行、用例或其他行为实体建模。
消息是两个对象之间的单路通信,从发送者到接收者的控制信息流。消息具有用于在对象间传值的参数。消息可以是信号(一种明确的、命名的、对象间的异步通信)或调用(具有返回控制机制的操作的同步调用)。
创建一个新的对象在模型中被表达成一个事件,这个事件由创建对象所引起并由对象所在的类本身所接受。创建事件,作为从顶层初始状态出发的转换的当前事件。对于新实例是可行的。
消息可以被组织成顺序的控制线程。分离的线程代表并发的几个消息集合。线程间的同步通过不同线程间消息的约束建模。同步结构能够对分叉控制、结合控制和分支控制建模。
消息序列可以用两种图来表示:顺序图(突出消息的时间顺序)和协作图(突出交换消息的对象间的关系)。
8.4 顺序图
顺序图将交互关系表示为一个二维图。纵向是时间轴,时间沿竖线向下延伸。横向轴代表了在协作中各独立对象的类元角色。类元角色用生命线表示。当对象存在时,角色用一条虚线表示,当对象的过程处于激活状态时,生命线是一个双道线。
消息用从一个对象的生命线到另一个对象生命线的箭头表示。箭头以时间顺序在图中从上到下排列。
图8-1为带有异步消息的典型的顺序图。
图8-1 顺序图
8.5 激活
激活是过程的执行,包括它等待嵌套过程执行的时间。在顺序图中它用部分替换生命线的双道线表示。调用用指向由这个调用引起的激活的上部的箭头表示。当控制流程重新进入对象中的一个操作递归时,递归调用发生,但是第二个调用是与第一个调用分离的激活。同一个对象中的递归或嵌套调用用激活框的叠加表示。图8-2为含有过程控制流的一个顺序图,包括一个递归调用和一个对象的创建。
主动对象是激活栈中一组激活对象中的根对象。每个主动对象有由它自己的事件驱动控制线程,控制线程与其他主动对象并行执行。被主动对象所调用的对象是被动对象。它们只在被调用时接受控制,而当它们返回时将控制放弃。
如果几个并行控制线程有它们自己的利用嵌套调用的过程控制流,那么不同的线程必须用不同的线程名、颜色或其他方式辨别,以避免当两个线程在同一个对象中产生混乱。通常,在一个单独的图中最好不要混合使用过程调用和信号。
图8-2 带有激活的顺序图
8.6 合作图
协作图是一种类图,它包含类元角色和关联角色,而不仅仅是类元和关联。类元角色和关联角色描述了对象的配置和当一个协作的实例执行时可能出现的连接。当协作被实例化时,对象受限于类元角色,连接受限于关联角色。关联角色也可以被各种不同的临时连接所担当,例如过程参量或局部过程变量。连接符号可以使用构造型表示临时连接(《parameter》或《local》)或调用同一个对象(《self》)。虽然整个系统中可能有其他的对象,但只有涉及到协作的对象才会被表示出来。换而言之,协作图只对相互间具有交互作用的对象和对象间的关联建模,而忽略了其他对象和关联。图8-3为一个交互图。
图8-3 合作图
可以将对象标识成四个组:存在于整个交互作用中的对象;在交互作用中创建的对象(使用约束{new});在交互作用中销毁的对象(使用约束{destroyed});在交互作用中创建并销毁的对象(使用约束{transient})。设计时可以首先表示操作开始时可得的对象和连接,然后决定控制如何流向图中正确的对象去实现操作。
虽然协作直接表现了操作的实现,它们也可以表示整个类的实现。在这种使用中,它表示了用来实现类的所有操作的语境。这这使得对象在不同的操作中可以担当多种角色。这种视图可以通过描述对象所有操作的协作的联合来构造。
1. 消息
消息可以用依附于链接的带标记的箭头表示。每个消息包括一个顺序号、一张可选的前任消息的表、一个可选的监护条件、一个名字和参量表、可选的返回值表。顺序号包括线程的名字(可选)。同一个线程内的所有消息按照顺序排列。除非有一个明显的顺序依赖关系,不同线程内的消息是并行的。各种实现的细节会被加入,如同步与异步消息的区别。
2. 流
通常,在完整的操作中协作图包含对象的符号。然而,有时对象具有不同的状态并且必须弄明确表达出来。例如,一个对象可以改变位置,或者在不同的时刻它的关联有很大区别。对象可以用它的类与它所处的状态表示即具有状态类的对象。同一个对象可以表示多次,每次有不同的位置和状态。
代表同一对象的不同对象符号可以用变成流联系起来。变成流是从一个对象状态到另一个的转换。它用带有构造型《become》的箭头表示,并且可以用顺序号标记表示它何时出现(如图8-4)。变成流也可以用来表示一个对象从一个位置到另一个位置的迁移。
构造型《copy》不经常出现,它表示通过拷贝另一个对象值而得到的一个对象值。
表8-1表示了几种对象流的关系。
图8-4 变成流
表8-1 流关系的种类
3. 协作图与顺序图
协作图和顺序图都表示出了对象间的交互作用,但是它们侧重点不同。顺序图清楚地表示了交互作用中的时间顺序,但没有明确表示对象间的关系。协作图清楚地表示了对象间的关系,但时间顺序必须从顺序号获得。顺序图常常用于表示方案,而协作图用于过程的详细设计。
8.7 模板
模板是一个参数化的协作,并有表示何时使用该协作的标线。参数可以被不同的值替代从而产生不同的协作。参数通常为类指定槽。当模板实例化时,它的参数受限于类图中的实际类或受限于更大的协作中的角色。
模板用一个虚线椭圆表示,椭圆用标记有角色名字的虚线与每个类联系。例如,图8-5表示摘自[Gamma-95]的Observer模板的使用。在这个模板的使用中,CallQueue替代Subject角色,SlidingBarlcon替代handler角色。
模板可以出现在分析、结构设计、详细设计和具体实现等不同层次中,这是重用经常出现的结构的一种方法。图8-5表示了Observer模板的使用。
图8-5 模板的使用
本文地址:http://com.8s8s.com/it/it2084.htm