![设计模式就该这样学:基于经典框架源码和真实业务场景](https://wfqqreader-1252317822.image.myqcloud.com/cover/758/33114758/b_33114758.jpg)
2.2 时序图
时序图(Sequence Diagrams)描述对象之间消息的发送顺序,强调时间顺序。时序图是一个二维图,横轴表示对象,纵轴表示时间,消息在各对象之间横向传递,按照时间顺序纵向排列。用箭头表示消息,用竖虚线表示对象生命线。
2.2.1 时序图的作用
(1)展示对象之间交互的顺序。将交互行为建模为消息传递,通过描述消息如何在对象间发送和接收来动态展示对象之间的交互。
(2)相对于其他UML图,时序图更强调交互的时间顺序。
(3)可以直观地描述并发进程。
2.2.2 时序图组成元素
时序图组成元素主要包括角色(Actor)、对象(Object)、生命线(Lifeline)、控制焦点(Focus of Control)和消息(Message),其具体解释如下表所示。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt003_18.jpg?sign=1738983364-TTmryCpvZ0RinQNtMnWp5GIR1FMAi1gT-0-afe5eaf62a1db1f852dcac90b3b2734f)
2.2.3 时序图组合片段
组合片段(Combined Fragments)用来解决交互执行的条件和方式,它允许在时序图中直接表示逻辑组件,用于通过指定条件或子进程的应用区域,为任何生命线的任何部分定义特殊条件和子进程。组合片段共有13种,名称及含义如下表所示。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt003_19.jpg?sign=1738983364-cICQo1lgV9JNyBT0CzTkxDS7SqLSCFmd-0-cce19ba378437146a17ec48297e904d1)
常用组合片段举例如下。
1.抉择(Alt)
抉择用来指明在两个或更多消息序列之间的互斥的选择,相当于经典的if...else。抉择在任何场合下只发生一个序列。可以在每个片段中都设置一个临界来指示该片段可以运行的条件。else的临界指示其他任何临界都不为true时应运行的片段。如果所有临界都为false并且没有else,则不执行任何片段,如下图所示。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt003_20.jpg?sign=1738983364-wjbJGmKdX4KcquBPHbq8Pu11YGgXdE7c-0-1f1d4d4e47760278f86c627ce627139d)
2.选项(Opt)
包含一个可能发生或不发生的序列,如下图所示。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt003_21.jpg?sign=1738983364-MXLQOHZztoioCFA1aruVTQQSgZHygeaf-0-9da581d898820efb41fa964be7e67791)
3.循环(Loop)
片段重复一定次数,可以在临界中指示片段重复的条件,如下图所示。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt003_22.jpg?sign=1738983364-JgEOPm1nbHNVFyXhEoGHzw5qWNbyGMgz-0-20b6259736847fe60f82a49e95b1b13d)
4.并行(Par)
并行处理,片段中的事件可以并行交错,Par相当于多线程,如下图所示。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt003_23.jpg?sign=1738983364-dIT9RWIl8Jeh2fdod0HO0s1wcnWbrK1L-0-00da24c380027fd641d6ac072340fb7d)
2.2.4 时序图画法及应用实践
时序图的绘制步骤可简单总结如下。
(1)划清边界,识别交互的语境。
(2)将所要绘制的交互场景中的角色及对象梳理出来。
(3)从触发整个交互的某个消息开始,在生命线之间从上到下依次画出所有消息,并注明每个消息的特性(如参数等)。
假设有如下一段代码。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt003_24.jpg?sign=1738983364-X0gnWTMsTgEZmlpFQjzCUB45P1OoiHH0-0-8073c17029c3fe10ee17119696d53903)
上面代码执行对应的时序图如下。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt003_25.jpg?sign=1738983364-jaj4WX4Iqx1c8yHPeUS09EFpfMGRq1Nw-0-e91b816bf93a19b74dead2c4ccac7c29)