1、交互作用图,(顺序图和协作图),1 交互图概述,交互图(interaction diagram)是用来描述对象之间以及对象与参与者之间的动态协作关系以及协作过程中行为次序的图形文档.,交互图通常用于描述一个用例的行为, 显示该用例中所涉及的对象及对象之间消息传递情况.,交互图包括: 顺序图(sequence diagram), 描述对象按照时间顺序的消息交换; 协作图(collaboration diagram), 描述系统成分如何协同工作.,顺序图是一种交互图,描述对象之间的动态交互关系,着重体现对象间消息传递的时间顺序 对象(Object):对象、对象的生命线、对象的控制焦点和对象的删除
2、消息(Message):简单消息、同步消息、异步消息、返回消息 交互片段(Interaction Frame):分支、循环,-3-,顺序图是显示对象之间交互的图, 这些对象是按时间顺序排列的. 它显示参与交互的对象及对象之间消息交互的顺序.,对象的三种命名方式:,生命线是对象图标向下延伸的虚线, 表示对象生存时间.,消亡点,控制焦点(Focus of Control)又称为激活期(Activation), 用生命线上的小矩形表示, 在这个时间段内, 对象执行相应的操作.,同步消息 异步消息 返回消息 创建消息 销毁消息 (简单消息:针对同步与异步消息),2. 顺序图中的消息,对象之间普通消息传
3、递对象自身消息传递返回消息对象之间过程调用对象之间异步消息,发送消息后不管消息是否被 接受,继续进行下一步处理,调用消息:消息的发送者把控制传递给消息的接收者, 等待接收者返回或放弃控制.,调用消息必有一个与之配对的返回消息, 但是可以不用画出.,(1). 同步消 息同步消息(synchronous message)代表一个操作调用的控制流。同步消息的发送者把控制传递给消息的接收者,然后暂停活动,等待消息接收者的应答,收到应答后才继续自己的操作。,(2)异步消息异步消息(Asynchronous message)消息的发送者把控制传递给消息的接收者,然后继续自己的活动,不需等待接收者返回信息或
4、控制。下面示例演示了如何在登录文件的情况下使用异步消息。,(3) 简单消 息它只表示控制如何从一个对象传递给另一个对象,而没有描述通信的任何细节。这种类型的消息主要用于通信细节未知或者无需考虑通信细节的场合。也就是说,主要用于不知道消息是同步还是异步的场合,但通常情况下表示异步消息此外在高层分析中,有时候没有必要指定一个消息是同步的还是异步的。如下面的示例所示。,创建消息:创建一个对象,箭头需要指到所建立的对象上面。 销毁消息:销毁一个对象,对象生命线用差号来表示销毁,表示被销毁对象的生命周期将到此终结。,旅店预订系统,16,-17-,旅店预订系统中识别分析类,-18-,绘制VOPC类图,-1
5、9-,-20-,实例-旅游申请系统中的分析类,-21-,进行职责分配,-22-,绘制VOPC类图,-23-,利用分析操作表示职责,-24-,为分析类添加属性,-25-,实体类之间的关联关系,-26-,旅游申请系统实体类类图,3. 顺序图中的结构化控制序列性的消息能很好地说明单一的线性的序列,但是我们通常需要展示条件和循环。有时候我们想要展示多个序列的并行执行。在顺序图中用结构化控制操作符能展示这种高层控制。为了表示顺序图的边界,可以把顺序图用一个封闭的矩形包围起来,并在矩形的左上角放一个小五边形。在这个小五边形内先写上sd,再后面写出图的名字。对每个子顺序图加上一个矩形区域作为外框,再在其左上
6、角放一个小五边形,在这个小五边形内写上用来表明控制操作符的类型的文字。,可选执行 标签是opt。如果控制进入该操作符标识的交互区域时监护条件成立,那么执行该交互区域。监护条件是一个用方括号括起来的布尔表达式,它要出现在交互区域内部第一条生命线的顶端,在其中可以引用该对象的属性。 条件执行 标签为 alt。用水平虚线把交互区域分割成几个分区,每个分区表示一个条件分支并有一个监护条件。如果一个分区的监护条件为真,就执行这个分区,但最多只能执行一个分区。如果有多于一个监护条件为真,那么选择哪个分区是不确定的。若没有应对措施,在模型中要避免这种情况。如果所有的监护条件都不为真,那么控制流将跨过这个交互
7、区域而继续执行。其中的一个分区可以用特殊的监护条件else,这意味着如果其他所有区域的监护条件都为假,就执行该分区。 并行执行 标签是 par。用水平虚线把交互区域分割为几个分区。每个分区表示一个并发计算。当控制进入交互区域时并发地执行所有的分区;在并行分区都执行完后,那么该并行操作符标识的交互区域也就执行完毕。每个分区内的消息是顺序执行的。需要指出的是,并发并不总是意味着物理上的同时执行。并发其实是说两个动作没有协作关系,而且可按任意次序发生。如果它们确实是独立的动作,那么它们还可以交叠。 循环(迭代)执行 标签是 loop。在交互区域内的顶端给出一个监护条件。只要在每次迭代之前监护条件成立
8、,那么循环主体就会重复执行。一旦在交互区域顶部的监护条件为假,控制就会跳出该交互区域。,顺序图的结构控制 可选执行(Optional Execution) 标记为“opt”。 条件执行(Conditional Execution) 标记为“alt”。 并行执行(Parallel Execution) 标记为“par”。 循环执行(Loop/Iterative Execution) 标记为“loop”。,上图展示了一个简化了的例子,其中有一些控制操作符。用户启动这个序列。第一个操作符是循环操作符,圆括号内的数字(1,3)表示循环执行的最少次数和最多次数。因为最少是一次,所以在检测条件之前主体至少
9、执行一次。在循环内,用户输入密码,系统验证它。只要密码不正确,那么该循环就会继续。但是,如果超过了三次,那么无论如何循环都会结束。 下一个操作符是可选操作符。如果密码是正确的,那么就执行这个操作符的主体;否则就跳过该顺序图后面的部分。这个可选操作符的主体内还包括了一个并行操作符。正如图中所表明的,操作符可以嵌套。并行操作符有两个分区:一个让用户输入帐号,另一个让用户输入数额。因为这两个分区是并行的,所以没有规定应该按照什么次序输入这两者,按照什么次序输入都可以。需要强调的是,并发并不总是意味着物理上的同时执行。并发其实是说两个动作没有协作关系,而且可按任意次序发生。如果它们确实是独立的动作,那
10、么它们就可以交叠;而如果它们是顺序的动作,那么它们可以按任意的次序发生。一旦并行操作符的两个动作都被执行过,那么该并行操作符也就执行完毕。在可选操作符中的下一个动作是银行向给用户交付现金。至此,顺序图执行完毕。,建立顺序图 步骤: 按照当前交互的意图,如系统的一次执行,或者一组对象(包括参与者实例,以下不再明确地提及参与者实例)之间的协作,详细地审阅有关材料(如有关的用况),设置交互的语境,其中包括可能需要的那些对象。 通过识别对象在交互中扮演的角色,在顺序图的上部列出所选定的一组对象(应该给出其类名),并为每个对象设置生命线。通常把发起交互的对象放在左边。 对于那些在交互期间要被创建和撤销的
11、对象,在适当的时刻,用消息箭线显式地予以指明。 决定消息将怎样或以什么样的序列在对象之间传递。通过首先发出消息的对象,看它需要哪些对象为它提供操作,它向那些对象提供操作。追踪相关的对象,进一步做这种模拟,直到分析完与当前语境有关的全部对象。如果一个对象的操作在某个执行点上应该向另一个对象发消息,则从这一点向后者画一条带箭头的直线,并在其上注明消息名。用适当的箭头线区别各种消息。,创建时序图,时序图工具条,时序图中增加对象和消息,对象规范,映射类,每个对象都应该映射到一个类。如果要为对象创建新的类,选择New选项。,消息规范,可以将接受对象的某个操作指定给消息。指定操作后,消息名变为所指定的操作
12、名,消息规范,设置消息同步类型,常用有简单,同步,异步;,静态结构模型:实体类的类图,类Title Isbn:String book:OID findTitle(isbn:String):OID 返回指定ISBN的Title对象的OID getTitle(oid:OID):Title 返回Title对象 getAvaliableBook():OID 返回第一个可借阅的Book对象的OID,类Borrower borrowerID:String loans:OID findBorrower(id:String):OID 返回指定ID号的Borrower对象的OID getBorrower(oid
13、:OID):Borrower 返回指定OID的Borrower对象 addLoan(loan:OID) 添加借阅记录 delLoan(loan:OID) 删除借阅记录,类Book id:Integer title:OID loan:OIDfindBook(id:Integer):OID 返回指定id的Book对象 getLoan():Loan setLoan(loan:OID) getTitle():Title getObject(book:OID):Book,类Loan Book:OID Borrower:OID Date:DatenewLoan(book:OID,borrower:OID,
14、date:Date) 创建Loan对象 getBook():Book getBorrower():Borrower,还书,添加借阅者,银行系统类图、顺序图,从上述分析可知,系统至少具有3个重要的类:Bank、Account、Customer。 在银行中,对帐户进行存钱、取钱、转帐操作,要保留业务记录。因此在系统中还应有代表这些业务记录的对象存在:存(Deposit)、取(Withdraw)、转帐(Transfer),这三个类都是一种业务记录,故可抽象出父类:Transaction。 接着需确定这些对象的属性和行为。,类BankGUI系统主界面示例图,类QueryDialog帐户查询对话示例图,
15、DWDialog界面(存款)示例图,DWDialog界面(取款)示例图,界面类AccountDialog示例图1,界面类AccountDialog示例图2,当按下主窗口的“注销帐户”或“修改帐户信息”按钮时,对话框QueryDialog弹出,操作员填写帐号并确定提交后,系统弹出对话框AccountDialog,显示帐户的详细信息。,界面类AccountDialog示例图3,类TransferDialog示例图,银行简化系统类图,(1)类Bank的属性和行为,bankCode: String name: String address: String Phone:String Fax:String
16、 setBankCode(code: String) setName(name: String) setAddress(address: String) setPhone(phone: String) setFax(fax: String)(设置私有属性),(1)类Bank的属性和行为,getBankCode(code: String) getName(name: String) getAddress(address: String) getPhone(phone: String) getFax(fax: String)(访问私有属性),(2)类Account的属性和行为,bank: Bank
17、 holder: Customer accountNo: String createDate: Date balance: float (私有属性) getHolders(): Customer newAccount(holder:Customer,balance:float):void remAccount(accountNo:String):void(销户) Withdraw(holderName:String,holderID:String,accountNo:String,money:float):float(返回取户余额) Deposit(holderName:String,hold
18、erID:String,accountNo:String,money:float):float(返回存款户余额),(2)类Account的属性和行为,transferOut(accountNo: String, bankCode: String, money: float): float transferIn(accountNo:String, bankCode: String, money: float): float newBalance(): float(计算新的帐户余额) update(): void(更新数据库中的帐户信息) save(): void(将帐户信息存储到数据库中) de
19、lete(): void(从数据库中删除帐户),(2)类Account的属性和行为,closeAccount(accountNo: String): void getAccount(accountNo:String): Account(返回指定贴的帐户信息) query(holderName:String,holderID:String, accountNo:String, money:float, isSaving: Boolean):Boolean(查询存取帐户是否存在,若是取款,还要查询帐户余额是否足够),(3)类Customer的属性和行为,Name: String customID:
20、 String address: String account: account getAccounts(): Account Query(name: String, id: String): Boolean newCustomer(name: String, id: String, address: String, account: Account ):void(创建客户对象) save(): void(将客户信息存储到数据库中) update(): void(更新DB中客户信息) hasAccount():Boolean(判断客户是否还持有帐户) delete(): void(删除DB中的
21、客户信息),(4)类Transaction的属性和行为,私有属性:account: Account createDate: Date fund: float(交易金额) newTransaction(account: Account, fund: float, date: Date): void save():void(将交易记录存储到数据库中),(5)类Deposit的属性和行为,继承类Transaction,无私有属性 newDeposit(account: Account, fund: float, date: Date):void(创建存款交易记录) save(): void(将存款交
22、易记录存储到DB中),(6)类Withdraw的属性和行为,继承类Transaction(同样有account,createDate及交易金额fund属性)。 无私有属性。 newWithdraw(account: Account, fund: float, date: Date): void(创建新的取款交易记录) save(): void(将取款交易记录存储到DB中),(7)类Transfer的属性和行为,继承类Transaction transferAccountNo: String transferBank:Bank newTransfer(account: Account, transferAccountNo: String, transferBank: Bank, fund: float, date: Date): void(创建新的转帐交易记录,可是收帐户或付帐户) save(): void(将转帐交易记录存储到DB中),“存款”的顺序图,“取款”的顺序图,“修改账户”的顺序图,