4.时序图sequence diagram
交互图interaction diagram描述了成群的对象如何以某种行为合作,其中最重要的是时序图sequence diagram。
典型的,一个时序图捕捉一单个情景的行为。图显示了一些示例对象以及这个用例里这些对象间传递的信息the messages that are passed between these objects within the use case
考虑一个简单的情景。我们有一个订单order,要用一个命令command来计算其价格。需要看订单上所有的行项目line items,并决定其价格,基于订单行产品的价格规则。处理完所有的行项目后,需要计算一个总和的折扣discount,基于跟客户相关的规则。
时序图通过给每个参与者一条生命线lifeline垂直向下来展示交互。见图4.1。
这些图中,我用anOrder的风格命名参与者participant。全语法是name : Class,如果你用class,则需要用冒号。
每条生命线有一个激活条activition bar,表示参与者在交互中何时是激活的。
命名很重要的,比如调用getProduct表示会返回aProduct。
第一个消息没有一个参与者来发送它,因为它来自一个未知的源,所以叫发现的消息found message。
见图4.2。
两种交互的不同:4.1是集中控制centralized control(一个参与者完成所有处理,其他参与者提供数据),4.2是分布控制distributed control(处理被分散到很多参与者,每个只做算法的一点点)
我更喜欢分布控制。好的设计的一个主要目标是将改变产生的效果局部化localize the effects of change。数据和访问数据的行为经常一起改变。所以将数据和使用它的行为放在一起是面向对象设计的第一条规则。
更多的,通过分布控制,你提高更多机会来使用多态而不是条件判断。
【创建和删除参与者】
创建一个参与者,你绘制一个消息箭头message arrow指向参与者盒子participant box。消息的名字是可选的如果你使用一个构造器,但我经常用new来标记。
删除一个参与者使用一个大的叉。在一条生命线的最后添加一个大叉表示删除自己。
在垃圾回收环境中,你不用直接删除对象,但仍然值得使用X来表示何时一个对象不再需要并可以被回收。
见图4.3。
【循环loop,条件conditional】
如果你想展示控制结构,最后用活动图activity diagram或代码。时序图是对象们如何交互的视觉化,而不是一个模型控制逻辑的方式。
循环和条件使用交互框interaction frame。见图4.4。
procedure dispatch
foreach (lineitem)
if (product.value > $10K)
carefule.dispatch
else
regular.dispatch
end if
end for
if (needsConfirmation) messenger.confirm
end procedure
一般,框由一个时序图拆分的片段fragment的一些区域region组成。每个框有一个操作者operator,每个片段有一个守卫guard。显示一个循环,你用loop操作符和一个片段,并在守卫里放迭代的基础the basis of the iteration([for each line item])。对于条件逻辑,你可用alt操作符,并在各片段放一个条件。只有guard是true的片段才会执行。如果你只有一个区域region,有一个opt操作符。
uml1中使用迭代标记iteration marker和守卫guard。一个迭代标记是一个*加到消息名去。你可以添加一些文字到中括号去来表示迭代的基础(比如*[for each line item])。守卫是放到中括号里去的一个条件表达式(如[value > $10000]),表示只有守卫是真才会发送消息。在uml2中他们从时序图中移除,但在交流图中合法communication diagram。
交互框的操作符:
alt alternative可选的多个片段;只有条件是true的才会执行
opt optional可选;只有提高的条件是true才会执行,和只有一个通道trace的alt一样
par parallel并行;每个片段并行运行
loop 循环;片段可能执行多次,守卫表示迭代基础basis of iteration
region critical region重要区域;该片段同事只能有一个线程执行
neg negative;片段展示了一个无效的交互invalid interaction
ref reference索引:指向另外一个图标里定义的交互。这个框绘制来包括引入交互的生命线。你可以定义参数和一个返回值
sd sequence diagram时序图;用来包含一个完整的时序图如果你希望
我发现这些交互框太重量级了,并不比代码或伪代码好。我更喜欢伪消息pseudomessage。
【同步和异步调用】
如果发送同步消息,则必须等到消息完成。如果发送一个异步消息,则可继续处理,不用等到回应。
我建议使用半箭头来表示异步消息更容易引人注意。
【何时用时序图】
如果你想关注一个用例几个对象的行为。时序图擅长展示对象间的合作,不擅长行为的精确定义。
如果你想关注一个对象在多个用例里的行为,用状态图。如果你想关注一个在多个用例或线程里的行为,考虑用活动图。
如果你想快速探索多个可选的交互,你可能最好用CRC卡,因为不用绘制和擦除。
其他有用的交互图的形式是交流图(显示连接connection),时间图(显示时间限制)。
CRC卡见P55。