第九章协作图本章要介绍与前一章的顺序图类似的一种UML图。这种图展示出对象之间的交互,但是绘图的方式与顺序图有所不同。本章将学习下列内容:●什么是协作图。●运用协作图。●使用“if”和“While”条件。●嵌套。●主动对象和并发。●同步。与顺序图一样,协作图也展示对象之间的交互关系。它绘制出对象和对象之间的消息连接。也许你会问:顺序图不也是做这件事吗,为什么UML中还要引入协作图呢?是不是多余了?顺序图和协作图很相似。实际上两者是语义等价的。也就是说这两种图表达的是同一种信息,并且可以将顺序图转换为等价的协作图,反之亦然。既然UML中引入了这两种图,那么它们就都应该有用。顺序图强调的是交互的时间顺序。协作图强调的是交互的语境和参与交互的对象的整体组织。还可以从另一个角度来看两种图的定义:顺序图按照时间顺序布图,而协作图按照空间组织布图。这两种图可以反映在开发过程的分析阶段中两种不同的思考过程。协作图能够阐明对象之间的关系,因为它包括对象之间的关联线。而顺序图则重点说明对象交互的时间顺序。一个组织中或许包括了思维方式不同的人。在提交这些图时,对不同场合的不同人,需要为他们提供不同的图。9.1什么是协作图对象图展示出对象和对象之间的静态关系。协作图是对象图的扩展。协作图除了展示出对象之间的关联,还显示出对象之间的消息传递。通常在协作图中省略掉关联的多重性,因为表示出多重性会使图变得混乱。关联线附近的箭头线表示对象之间传递的消息,箭头指向消息接收对象。消息名称和消息序号附在箭头线附近。消息的一般作用是触发接收消息的对象执行它的一个操作。消息名后面一般有一个双括号,说明它代表的是操作。在双括号内可以指明操作需要的参数。上面说过,可以将顺序图转换成协作图,反过来也成立。因此在协作图中也应能表示出消息的顺序。可以在消息名前面加上消息的序号,它代表该消息在消息序列中的序号。消息名和序号之间用冒号隔开。下图说明了协作图中的图符集。我们将利用协作图和顺序图语义等价这一基本原理来学习协作图中的概念,让我们重新看看上一章中介绍的有关顺序图的例子。将这些顺序图用协作图画出,就可以了解协作图的概念。9.2图形用户界面(GUI)这个例子是个最简单的例子,一名参与者通过击键发起了交互序列,并且在序列总引发消息。交互序列如下所述(根据前—章的例子):1.GUI将击键事件通知给操作系统。2.操作系统接着通知CPU。3.操作系统更新GUI数据。4.CPU又通知图形卡。5.图形卡向显示器发送一个消息。下图说明了消息序列在协作图中如何表示。图中的人形图标代表了发起交互序列的参与者。在协作图中也可以表示出对象的状态变化。在对象的图标中可以注明对象所处的状态。在图中可以重复画出标注了不同状态的同一对象的图标。这样的两个图标之间用带箭头的虚线连接起来,并在虚线上使用构造型《become》来表示对象状态的变化。9.3饮料销售机当在协作图中加入条件表达式的时候,协作图就变得更有表达力了,就像上一章介绍饮料销售机的例子时那样。下面先来看看用例“BuySoda(买饮料)”的最理想场景下的交互序列:1.顾客向机器前端的槽缝中投入钱币。2.顾客做出一个选择,选择所要购买的饮料品种。3.钱币被转送给记录仪。4.由于这是—个理想情况下的场景,所以记录仪控制分配器将一罐饮料投递到销售机的前端。这个场景的协作图如下图所示。下面再看“钱数不正确”场景的协作图。这个协作图中要出现以下几个条件:1.用户输入的钱数超过了所要购买的饮料价格。2.饮料销售机中备有可找给顾客的零钱。3.饮料销售机中没有可找给顾客的零钱。在协作图中条件的表示方法与在顺序图中一样,都是用方括号将条件表达式括起来,放在消息名的前面。但是要注意的是消息的条件和序号之间的匹配关系。条件和序号可能会使图变得复杂,因此让我们一步一步地来建立这个场景的协作图,这个图的前提条件是用户输入的钱比所要购买的饮料价格高,并且机器中备有找给顾客的零钱。首先增加机器给顾客找零的消息,并为该消息附加上条件。给顾客找零消息是检查是否有找给顾客的零钱这一消息的直接后续消息。为了表明两条消息之间的这种关系,这两个消息采用同一序号,用序号后面的点再接序号来区分它们。这叫做消息嵌套(nesting)。下图说明了这个顺序图的细节。如果机器中没有零钱可找会怎么样呢?销售机必须显示一条“无零钱”信息提示给顾客,并将顾客投入的钱币退出,提示顾客投入零钱。实际上,这时交易就结束了。要增加这个条件,就要增加控制流的分支。可以用嵌套序号表示这个控制流的序号。因为它是第2个被嵌套的消息,因此圆点后面的序号是2。最后,由于交易已经结束,该消息上要附加构造型《transactionover》来表明交易结束。此外还有另—个发送饮料的消息。下图是这个场景的顺序图。9.4创建对象为了说明在协作图中如何表示创建新对象,让我们回顾上一章介绍的咨询公司的例子中的用例“createaproposal(创建一个提案)”。这个用例的步骤序列是:1.顾问想要重用一个提案的某部分,然后开始在网络中的中央数据仓库中搜索该提案。2.如果顾问找到了一个合适的提案,他就用Office软件包打开该提案文件并编辑它,然后保存这个文件,从而建立了一个新提案的新文件。3.如果顾问没有找到提案,则他就直接打开Office软件包建立一个提案的新文件。4.在编辑和创建提案时,顾问要运行Office软件包中的应用程序。5.当顾问完成提案时,他要将这个提案保存到网络中央数据仓库中。在消息上附加构造型《create》可以表示该消息创建了新的对象。这里要用到“if”条件和嵌套消息,此外还要用到“while”循环条件。“while”循环条件的表示法和在顺序图中一样,条件表达式用方括号括起来,方括号前面再加上一个星号。下图是这个用例的协作图,其中包括对象创建消息和“while“循环条件。9.5其它概念9.5.1发送给多对象的消息一个对象可能会向同一个类的多个对象同时发送一个消息。例如,老师会让多个学生同时交作业。在协作图中,多对象(multipleobject)用“一叠向后延伸的多个对象图标”表示。在多对象前面可以加上用方括号括起来的条件,前面加一个里号,用来说明消息发送给多个对象,如下图所示。有时,按顺序发送消息是很重要的。例如,银行出纳员(BankClerk)要按照顾客排队的次序为每名顾客(customer)服务。可以用“while”条件表达出消息的顺序(例如“lineposition=1...n”)。9.5.2返回结果消息可能是要求某个对象进行计算并返回结果的值。例如一个顾客对象可能请求一个计算器(Calculator)对象计算某项商品的总价,包括该项商品的价格和税款。UML提供了返回值的表示法。返问值的名字在最左,后跟赋值号“:=”,接着是操作名和操作的参数。对计算商品项价格这个例子,可以表示成:totalPrice:=compute(itemPrice,salesTax)。下图说明了在协作图中的返回值的表示法。表达式中赋值号的右边部分被称为消息型构(messagesignature)。9.5.3主动对象在一些交互中的控制流是由一个特定的对象控制的。这样的对象叫主动对象(activeobject)。一个主动对象可以向被动对象发送消息也可以与其他主动对象交互。在图书馆的管理中,图书馆管理员(Librarian)从主顾(Patron)那里获得参考资料的信息,然后到数据库里去查找这些参考资料,然后回复主顾提出的问题,指派工人(Worker)进新书。一个图书馆管理员也要和做同样事情的其他图书馆管理员交互。两个或者多个主动对象同时工作时的情形被称为并发(concurrency)。在协作图中,主动对象的表示法除了矩形框边界要加黑加重外,其他方面与一般对象的表示法相同。9.5.4同步有时遇到的另一种情况是一个对象只能等到其他一些对象发送了消息(可能是不连续的发送消息)后才能发送消息。也就是说,这个对象必须要“同步”自己发送的消息与其他对象发送的消息。下面的例子将说明什么是同步。假设这里的对象是一个公司里参与新产品的商业活动的人员。如下是这些对象的交互序列:1.高级市场主管(SeniorVPofMktg)要求销售主管(VPofsales)为某一新产品制定一份促销计划(campaign)。2.销售主管指定了一份新产品促销计划并将这个任务指派给一个销售经理(SalesMgr)。3.销售经理要求一名销售员(Salesperson)根据促销计划销售产品。4.销售员与几位可能购买新产品的顾客通电话,向他们推销。5.在销售主管分配了促销任务和销售经理根据计划要求销售员执行后(也就是步骤2和步骤3结束后),公司的公共关系专员(PRSpecialist)在当地的一家报纸上发布了关于这次促销的广告。如何在协作图中表示步骤5呢?UML同样为同步提供了表示法。不是在消息前加序号来表示同步,而是在需要同步的消息之前列出在这个消息之前要传递的消息序号。序号之间用逗号分开,最后用反斜杠与需要同步消息隔开。下图说明了协作图的这种表示法。9.6小结协作图是表达顺序图中所有信息的另一种UML图。协作图和顺序图是语义等价的。尽管如此这两种图在建立系统的模型时部很有用。顺序图按照时间组织,协作图按照空间组织。协作图展示了对象和对象之间的关联,还展示了对象之间的消息传递。关联线旁的消息箭头代表一个消息,消息前的序号代表消息发送的时间顺序。条件的表示与在顺序图中相同——将条件表达式用方括号括起来加在图中。“while”循环条件的方括号前要加一个星号。消息之间有从属关系。协作图中的消息序号命名方案与技术文章中的标题和子标题的命令类似——使用圆点来说明嵌套的层次。协作图中可以表示出一个对象按照指定的次序(或无次序)地向一组对象发送消息。还可以表示拥有消息控制流的主动对象,以及消息之间的同步。作业:1.在饮料销售机的例子中,只给出了与用例“BuySoda”的“钱数不正确”场景的实例顺序图所对应的协作图。为这个用例的所有场景建立一般顺序图所对应的协作图。也就是要在图中加上“无存货”场景。