•交互与交互图
交互的概念
•一次交互就是指在特定语境中,为了实现某一个目标,而在一组对象之间进行交换的一组消息所表示的行为
消息
UML中的4种交互图
•顺序图:顺序图是一种强调消息时间顺序的交互图,为读者提供了控制流随着时间推移的清晰的可视化轨迹
•通信图:UML 2.0中的通信图实际上就是UML 1中的协作图,它强调的是参加交互的对象的组织,为读者提供了在协作对象结构组织的语境中观察控制流的一个清晰的可视化轨迹
•定时图:采用了一种带数字刻度的时间轴来精确地描述消息的顺序
•交互概述图:是交互图和活动图的混合物
•如何阅读交互图
阅读顺序图
顺序图的主要元素
•对象与角色:最顶上一排矩形框。在交互图中,参与交互的对象既可以是具体的事物,又可以是原型化的事物。作为具体的事物,一个对象代表现实世界中的某个东西。例如,aOrder作为类Order的一个实例,可以代表一个特定的订单;而如果作为一个原型化的事件,则aOrder可以代表类Order的任何一个实例。
•生命线与控制焦点:每个对象都有自己的生命线,对象生命线是一条垂直的虚线,用来表示一个对象在一段时间内存在。
•消息:用来描述对象之间所进行的通信的,该信息带有对将要发生的活动的期望。当传送一个消息时,它所引起的动作是用一个通过对计算过程的抽象而得到的可执行语句(就是方法头)。
•消息分为五种:调用、返回、发送、创建和销毁
•调用:表示调用某个对象一个操作
•顺序编号(第几步的编号):整个消息的传递过程就形成了一个完整的序列,因此通过在每个消息的前面加上一个用冒号隔开的顺序号来表示其顺序。除了顺序编号之外,还可以采用嵌套方案:
读图小结
•第1步 在dispatchForm(分发窗体)中,对于某个已支付的Order进行分发时,就会调用该订单(一个Order类的实例对象aOrder)的dispatch()方法
•1.1 dispatch()方法将逐个调用 [for each orderitem] 该Order对应的所有OrderItem对象的getPeddleryId()方法获取供应商ID 1.2(PeddleryId),1.1.1 而OrderItem对象则是通过其所对应的Product对象来的getPeddleryId()方法来获取供应商ID 1.1.2
•当Order的实例对象aOrder得到返回的PeddleryId后,根据该值判断是否已经有相对应的DeliverOrder对象【if PeddeleryId Not Exist】,如果没有就创建它(调用 1.3 create(PeddleryId)),然后再将对应的Product添加到这个DeliverOrder对象中。[else ] 1.4否则就直接添加到相应的DeliverOrder对象中
嵌套,由左向右,由上向下
•循环与分支
交互片断操作符
片段就是指上面的框,
左上角是片段操作符
assert(断言)
一定会发生
•交互片断操作符assert是用来表示内容所描述的行为是执行过程中那个时刻唯一的有效行为。如果执行到这个片断的前面,则说明该片断就一定会发生。它通常和ignore或consider一起使用,以断言某种特定种类的消息行为
break
条件复合跳出
•交互片断操作符break和循环语句的break有点类似,通常break用来定义一个含有监护条件的子片断。
如果监护条件为“真”则执行子片断,而且不执行包含子片断的图中其它交互将不会执行,也就是跳出去;
如果监护条件为“假”,那么执行将正常地继续进行
critical
连续性的事物性的操作
•表示该子片断是“临界区域”,在临界区域中生命线上的事件序列不能够和其它区域中的任何其他事件交错。通常用来表示一个原子性的连续操作,例如事务性操作
par
同时执行
•用来表示“并行”的,也就是用来表示两个或多个并发执行的子片断,并行子片断中单个元素的执行次序可以以任何可能的顺序相互操作
ref
引用另一个片段到此处
•在一个交互图中,我们可以引用其它的交互图,其表示的方法是用一个矩形,加上ref操作符,并写明引用的交互图名称即可
图 | 表示法 | 图 | 表示法 |
类图 | class | 对象图 | object |
包图 | package | 用例图 | use case |
顺序图 | sd | 通信图 | comm |
定时图 | timing | 活动图 | activity |
交互概观图 | intover | 状态机图 | statemachine |
构件图 | component | 部署图 | deployment |
阅读通信图
通信图就是把顺序图竖起来去看,关注了访问关系。
通信图主要元素
•链:连接器,是用来表示对象之间的语义连接,一般而言,链是关联的一个实例(包括《association》、《self》、《global》、《local》等)。不过在UML 2中已经开始弱化它们的使用,因此除非必要,无需过多地考虑它们
•消息编号:消息的编号有两种,一种是无层次编号,它简单直观;另一种是嵌套的编号,它更易于表示消息的包含关系(类似,1.3.2 )
•迭代标记:用*号表示,表示循环,通常还有迭代表达式,用来说明循环规则
•监护条件:通常是用来表示分支的,也就是表示“如果条件为true,才发送消息”
•在通信图中使用监护条件一定要有所限制,通常应只列出主要的监护条件,否则会影响其阅读。如果需要,尽可能还是通过顺序图来表示
•如何绘制交互图
准备工作
•首先根据自己的喜好和实际的表现需要来选择顺序图或通信图。不过由于它们在语义上是等价的,因此可以绘制出一种,再通过建模工具来自动转换成另一种图
•分析模型中的交互图彻重于分析类的职责分配和交互流程,而设计模型中的交互图则彻重于设计类的引入和实际方法的调用与流程控制
•先确定参与交互的对象、对象之间的关系(通信图),然后确定对象间的消息交互流程(用同步调用、异步消息、返回消息表示),并利用交互片断(顺序图)或迭代标记及监护条件来表示循环和分支结构
鲁棒分析
鲁棒图可以很多的解决需求分析和架构设计之间的差别。更详细的说明请看最后的解释。
•Robustness分析不是UML模型的一部分,它是一个强大的草图工具,是介于分析和设计之间的一种有效工具
•在Robustness分析中,将应用边界类、控制类和实体类,分别对应MVC 架构的3个层
•从一个用例中抽取三类对象的方法:
鲁棒分析—从事件流开始
下面是用例描述
鲁棒分析—寻找边界对象
•图书管理员向系统发出“新增书籍信息”请求——主窗口、“新增书籍信息”按钮
•系统要求图书管理员选择要新增的书籍是计算机类还是非计算机类——书籍类别列表框。
•图书管理员做出选择后,显示相应界面,让图书管理员输入信息,并自动根据书号规则生成书号——“新书信息录入”窗口及辅助的“提交”按钮
鲁棒分析—寻找控制对象和实体对象
•新添两个逻辑:
一 是基本事件流中的步骤2、3要求根据用户选择的类别,自动获得书号;
二 是当书名重复性检查没有通过(有重名),则应返回要求其重输
构建交互模型
转换成通信图
走到这里,我们已经能够知道,MDA的建模顺序,是先用例图,用例描述,鲁棒图,鲁棒顺序图(通信图),类图,数据库设计图
•交互图应用说明
交互模型的类型与演变
分析阶段的交互模型
•工作方法:针对用例图中的每个用例,并结合领域模型中的类,寻找分析类,并通过Robustness分析来理清业务逻辑流程,再用交互模型将其确定下来
•注意:主要关注于区分出边界对象、实体对象和控制对象,暂时不要考虑其具体的实现类
•说明:对于较复杂的用例,可以按上述的流程逐渐地进行分析、设计、实施;但对于比较简单的用例而言,也是可以直接从用例描述中导出设计阶段交互模型
分析阶段的交互模型之后
•引入基础类:包括基础框架、程序库等
•质量评审:
-- 低耦合:耦合性是指两个类之间的连接强度
-- 高内聚:内聚性是指一个类的属性与方法高度集成
-- 效率:解决方案的执行效率是否满足系统的需求
-- 完整性:是指在任何环境下都可以重复使用
-- 简单性:类越简单,出错的可能性越小,系统的灵活性和可维护性也越好
• 优化类设计:阅读 《设计模式与重构》
设计阶段的交互模型 & 交互建模要点
•在分析模型的基础上引入基础类、优化类设计之后,必然会获得新的类模型(类图)(设计模型),因此就可能需要基于新引入的“设计类”来更新交互模型,以获得与实际代码相吻合的模型
•给出一个能表达其目的的名称;通过修改元素的布局,尽量避免交叉线的存在;可以通过注解和颜色作为可视化提示,以突出图形中的重要特性;尽量少用分支,对于分支很多的场景,可以考虑用活动图来补充
•定时图(时序图)
定时图与顺序图的区别
•坐标轴交换了位置,改为从左到右来表示时间的推移(生命线颠倒)
•用生命线的“凹下凸起”来表示状态的变化,每个水平位置代表一种不同的状态,状态的顺序可以有意义、也可以没有意义
•生命线可以跟在一根线后面,在这根线上显示些不同的状态值
•可显示一个度量时间值的标尺,用刻度表示时间间隔
•本章小结
•首先介绍了交互的概念,并延伸出UML中的4种交互图
•以为“从订单生成送货单”场景绘制的顺序图为例,介绍了对象与角色、生命线与控制焦点、消息、顺序编号、循环与分支、交互片断操作符等基本概念
•以等价的通信图为例,介绍了通信图的基本概念
•演示了如何采用Robustness分析法,从一个用例的事件流描述中导出相应的交互模型
•讨论了交互模型的实际应用
•介绍了定时图的基本特点
内容源自:面向对象设计PPT
鲁棒分析
概念性架构设计可以分为以下3步:
1. 鲁棒性分析
2. 引入架构模式
3. 质量属性分析
很多人认为从需求分析到架构设计之间的过渡遇到很多问题,究其根源,可能是以下的原因造成的:
- 用例是面向问题领域的,而设计是面向机器域的,这两个‘空间’存在映射。
- 用例技术本身不是面向对象的,而设计应该是面向对象的,这是两种不同的思维方式。
- 用例规约采取自然语言描述,而设计采取形式化的模型描述,描述的方式不一样。
鲁棒图可以很多的解决需求分析和架构设计之间的差别。
鲁棒图包含3中元素:边界对象、控制对象和实体对象。
边界对象是模拟外部环境和未来系统之间的交互进行建模,它负责接收外部输入、处理内部内容的解释,并表达或者传递相应的结果。也就UI部分,负责交互
控制对象对行为进行封装,描述用例中事件流的控制行为。也就是业务方法,负责控制
实体对象对需要存储的信息进行描述,它往往来自领域概念,和领域模型中的对象有良好的对应关系。也就是简单对象类 PO。负责信息
鲁棒图的三种对象很好的概括了实际系统 中对象的三种职责:交互、控制和信息。这三种职责和组成架构的抽象元素之间有完美的对应关系:连接元素、处理元素、数据元素。
鲁棒图的本质:
- 参与者只能同边界对象进行交谈
- 边界对象只能同控制体和参与者进行交谈
- 实体对象也只能同控制对象进行交谈
- 控制体既能与边界对象交谈,也能同控制对象进行交谈,但不能与参与者进行交谈。
可以将MVC结构和鲁棒图进行对应,View对应边界对象,Model对应实体对象,Controller对应控制对象。当然,有时Model中也包含一部分控制对象。
要建立概念性架构,应明确实现预期功能所需的职责模型,研究用例执行的不同场景是一个可取的方法。
所谓软件架构就是关于如何构建软件的一些最重要的设计决策,这些决策往往围绕着将系统分为哪些部分、各部分之间如何交互展开的。
软件架构模式就是高度抽象的、适用于许多类似系统的、预先定义好的一种特殊的软件架构。架构模式描述了软件系统基本的结构化组织方案,具体而言,架构模式提供了一套预定义的子系统,并规定了子系统的职责,以及子系统或自荐关系的组织原则和组织指南。
目前有很多比较成熟的架构模式,我们需要根据项目的具体需求去确定应该采取哪种架构模式。
分层:很流行,最大的优点是将整体问题局部化,把可能的变化分别封装在不同的层中,最后,系统被规划为一个单向依赖的分层体系,利于修改、扩展和替换。具体而言,各层之间的单向依赖关系可以分为两种:严格的分层架构要求第n层只能被第n+1层调用,于此相对的是不严格的分层架构,第n层可以被位于其上层的任意一层调用。我们需要注意分层的原则:职责划分和交互机制。
MVC:铺天盖地的一种模式。随着smalltalk发展而来,有很多变种。包含三种组件:Model、View、Controller。
微内核:最大的优点是适应变化。微内核架构不仅将应用相关部分与通用部分分离,而且又将通用部分进一步分离成一个最小化的基本服务内核和众多扩展服务。微内核不仅提供了一个基本服务的最小集合,这些基本服务屏蔽了其下层复杂环境的影响、并以规范的接口提供给上层的‘增值服务’使用,于是所有这些附加的增值服务都和复杂环境无关。微内核所提供的基本服务必须是完备的,从而实现了一个虚拟机。这个虚拟机不仅屏蔽了下层的复杂性,而且建立了更抽象、更易用的一个‘新机器’供其上层使用。
微内核的缺点:1.设计和实现的复杂性;2. 往往比同类情况下其他架构的性能低。
采取微内核架构的原因:1. 可扩展性;2. 可移植性;3. 延长软件系统的生命周期。
元模型架构:一个以适应变化、支持长生命周期为主要目标的架构模式。包括两个层:基本层和元层次。基本层定义应用,类似于我们要编写的程序;元层次包含一组‘元对象’,这些元对象组成的模型叫做‘元模型’,元模型是对基本层中的‘一切’的抽象,提供了软件本身的结构和行为的‘自描述’。