采用[ICONIX] 方法实践分析和设计之六 [时序图](转)

采用[ICONIX] 方法实践BLOG设计之六 [时序图]

在前几篇文章中,我们分别进行了域模型和用例建模,并使用 Robustness工具进一步分析验证
了相应用例的处理流程,并在相应模型(域模型)的基础上,通过Robustness方法引入相关的边界对
象,控制对象(控制器),并更新了相应域模型中类的属性(字段)。下面就可以进入到交互建模阶段
了。如下图:


    作为交互建模本身,就是要通过寻找对象之间的交互关系,进而进行方法(操作或行为)分配。

    正所谓“只有在所有的用例为所有事件进程建立了交互建模式之后,才可以确定已经发现系统所
需的每个对象所扮演的角色,以及它们的责任。
”              ------Ivar Jacobson

    而上面的那句话换言之就是仅当为每一个用例的所有基本流程和所有分支流程绘制时序图后,
才能确保发现了每一个对象的所有职责。

   有关于Ivar Jacobson这位UML祖师爷,我的感觉除了敬仰以外已没有别的词汇来形容了。他
就是健壮性图,时序图以及大名鼎鼎的“用例”的发明人,下面是摘自csdn对他的评价如下:
   在过去四十年以来,Ivar Jacobson 始终以其似火的创造热情和惊人的天赋,对整个软件产
业保持了非凡的影响,是屈指可数的几位世界级软件大师之一。他与Grady Booch和James Rum-
baugh三人一起创造了意义深远的UML,因此,他们三人被成合称为“UML三友”。《面向对象软件工
程》和《UML语言用户指南》等著作,已经成为殿堂级的软件经典著作。

    后面的链接就是他在CSDN上的最新视频:
        http://live.csdn.net/Issue252/LivePlay.aspx)

                                                  
    在UML中,交互建模包括两种形式:时序图(顺序图,Sequence diagram)和协作图(Co--
llaboration diagram)。

    UML的时序图是从Ivar Jacobson的对象交互图和 OMT中的事件跟踪图演变而来。它用来
描述对象之间动态的交互关系,着重体现对象间消息传递的时间顺序。它允许直观地表示对象的生
存期,在对象生存期内,对象可以对输入消息做出响应,并且可以发送消息。换言之,它可以让大
家从中容易找出事件发生的次序。对于每一个用例,您将绘制一张时序图,其中包含了该用例中的
基本流程和所有的分析流程。做为动态模型的核心,时序图在运行阶段的行为(包括系统将如何实
现这些行为)做了非常详细的定义。

    时序图基本上包含四种元素:
   
    描述操作流程的用例文本:位于时序图的左边,使用空白将文本分开,这样将容易知道哪句话
对应于右边的哪个元素。

    对象:使用包含两个名称的方框表示,是直接从健壮性图中搬过来的。这两个名称分别是类名
和对象名(实例编号),格式为 class:object;可省略其中的任何一个名称。也可以使用健壮性图
构造类型的方式来显示对象,这将有助于跟踪参与者,边界对象和实现对象之间传递的消息。

    消息:对象之间的箭头。消息箭头可位于两条虚线,直线和方法矩形之间或两个方法矩形之间。

    方法(操作):用位于虚线上的矩形表示,该虚线属于该方法所属的对象。可以使用矩形的长
度来反映拥有控制焦点的时间。控制焦点在理论上很有用,但实际上并非如此,因为大多数可视化
建模工具在这方面的功能都不太强。如果在时序图上显示控制焦点较难,只需关闭这种功能即可。

    另一种是强调组织的协作图, 它用来描述相互交作的对象之间的交互关系和链接关系。它与时
序图不同的地方是:时序图着重体现交互的时间顺序,协作图本身通过使用布局图着重体现交互对
象间的静态链接关系。它指明各个对象之间是如何静态相连,协同工作的。
  
    因为ICONIX强调使用时序图作为主要工具进行交互建模,所以下面所说的交互建模主要还是围
绕时序图展开的:)

    另外要强调的是在交互建模期间,要实现的三个主要目标:
    一. 在边界对象,实体对象和控制对象之间分配行为。如果这时还不清楚相关的边界对象,实
体对象和控制对象是什么,则此时考虑如何分配行为还为时过早,应返回到健壮性分析,对此进行
确定。
    二. 列出用例涉及的对象之间随时间的变化进行的详细交互。在运行阶段,对象是通过彼此发
送消息进行交互的。对于用例中的每个行为单元,都必须确定所需的消息/方法。
    三. 最终确定类间的方法(操作)分配。

    在ICONIX方法中绘制时序图需要4步:
    第一步:复制用例规范中的用例文本,将其粘贴到页面的左边。
    第二步:加入健壮性图中的实体对象。这些对象都是表示静态模型的类图中的类的实例。在绘
            制时序图时,如果发现遗漏的属性,一定要将其加入到静态查型中,这是编码前的最
            后一步了。
    第三步:另入健壮性图的边界对象和参与者。将边界对象加入到域模型中,因为这些对象属于
            解决方案空间,而域模型针对的是问题空间。在时序图中考虑边界对象时,您便将这
            两种空间集成起来了。
    第四步:决定将哪些方法分配给哪些类。将方法分配给类是,需要将健壮性图中的控制器转换
           (每次一个)为一组执行所需行为的方法和消息(有20%的控制器最后会转换为一个真
            正的控制对象)。在这个过程中,将健壮性图作为核对清单,以确保时序图考虑了要
            求的所有系统行为。另外,健壮性图中的一个控制器可被转换为时序图上的多个方法。


    好了,有了这些基本概念和知识的介绍和准备工作之后,开始今天的正文吧:)

    首先要绘制的用例时序图是:“登陆系统

    先将下面的用例文本粘贴到时序图中的左边

    用户名称: 登陆系统
    基本流程:
        用户在网站首页点击登陆链接,系统显示后台登陆页面。用户在登陆表单中输入其姓名,
    密码然后点击提交按钮。系统在确认该用户提交信息有效之后,初始用户相关信息。并返回首
    页。
    分支流程:
        如果用户没有提供姓名,系统将显示一条错误信息,来告之用户输入姓名。
        如果用户提供的密码不正确,系统将显示一条错误信息, 要求用户输入正确密码。

    然后是引入相应的实体对象(从健壮性图中找出),假设健壮性图如下所示:
  


      
    里面的实体对象是“用户信息列表”和“用户信息”,将它们引入到时序图中。

    接下来就是边界对象和参与者了。(这里要说明的是,因为通常情况下通过边界对象(类)来访
问系统,因此消息的开始方向通常是边界类,所以要将边界类和参与者放在左边。)

    经过这一番“折腾”,我们看到了如下的布局图: (prepare sequence)





    下面就将相应的方法引入到类中,其原则就是上面的“将健壮性图中的控制器转换(每次一个)
为一组执行所需行为的方法和消息(有20%的控制器最后会转换为一个真正的控制对象)”。

    我相信大家之前有不少人做过时序图,所以就将最终的分配结果放上来了 (如果大家认为有什
么错误或别扭的地方,可以在回复中讨论。同样下面的其它时序图也是如此)。






    而在Rose里通过“F5快捷键”可以很方便的用时序图生成协作图(Collaboration diagram),结
果如下:
     "登陆系统"用例的协作图:
   



    好了,完成了上面的例子之后,相信之前做没做过时序图的朋友心里都该有个底了,下面就把
“发表文章”这个用例的健壮性图和时序图发上来(这样做更于相互对照,并检查是否绘制正确):

    “发表文章”用例的健壮性图
   

     “发表文章”用例的时序图:


    
    下面贴出来的依次是接着是“浏览评论”,“删除评论”,“提交评论”


    “浏览评论”用例的健壮性图:
   
   
    “浏览评论”用例的时序图:




    "删除评论"用例的健壮性图如下:


     "删除评论"用例的时序图如下:
      


     "提交评论"用例的健壮性图如下:



    "提交评论"用例的时序图如下:






    完成了时序图的绘制,最后根据上述五张时序图绘制的结果将方法和操作赋给相应的类,并更
静态模型如下:
    



   当这一步完成后,这里有必要先做一下初步总结,让大家清楚的了解从这个系列开篇到目前所
讲的内容有一个大概的思路。那就是:

    首先从需求开始,产生域模型,用例模型这一静一动两个关键模型。然在在用例模型基本上,
进行Robustness分析,然后根据分析的结果找出实体对象,边界对象和控制对象,并通过一步步
的细化,从需求分析过渡到设计阶段。而在这一过程中,会发现在域建模阶段遗漏的对象,并引入
一些与设计更相关的对象。通过将这些对象分析并使之抽象化之后,更新相应的域模型使之逐步过
渡到静态类模型(类模型就是在领域阶段基本上加入设计阶段的思想)。


   在Robustness分析基础上,还可以对每个用例进行交互建模,这就是这篇文章所讲到的核心
内容。从而对类模型进行更新,得到相对完整的静态类模型。

   而下一篇要讲的就是在较完善的类模型基础上,进行“关键设计复核”,进行质量评审等工作了。


题外话:

    看了这个静态模型,大家肯定会有种感觉就是模型本身还缺了不少的类和操作,认为本人的
人品有什么问题,呵呵。其实这也是因为在这个系列文章一开始就提出的: “只分析重要需求”这
个“宗旨”所造成的 (当然这里的重要需求也没有都分析出来,主要还是写文章的时间太少, 真是
对不住了。感兴趣的朋友可以把那些认为漏掉的重要内容在ROSE文件补充上,以便有一次实践的
机会,我这里就偷个懒了)。

   另外这样做的一个原因就是如果面面俱到就会让大家有一种“只见树林,不见森林”的感觉,因
为这个系列文章主要讲的就是ICONIX方法本身,而在相应的每一篇文章中我也是尽可能侧重于方
法,而不是真正的去开发一个完整的BLOG系统。因此这里还是希望大家见谅和理解。

   还有就是笔者以前的设计开发过程中经常是先分析核心需求以及开发核心功能,然后再通过这
些主干所搭建的架构为基础进行其它功能模块的开发。我个人认为这应该是一种所谓“迭代增量
开发过程。

   我记得在这个系列开篇时也提到过ICONIX方法是一种支持迭代增量开发的方法。而在当代的软
件开发理论中,基本上都有这个特点:

    不管是RUP里面所讲述四步:初始(inception),细化(elaboration),构建(constr-
uction),交付(transition)。在每个阶段结束都有技术评审,以确定是否该进行下一阶段,而
在每个阶段又可以细化为多次迭代。

    还是XP(极限编程)中所说的最大化人的能量为核心目标,而里面所说的12个准则中的“每日
构建(小型发布)”,“计划游戏”等等,也是体现了迭代这一思想(甚至可以将“用户故事”看成
是用例的“近亲”)


    而回到我们这个开发系列上来,我们要在什么地方发生迭代呢?

    第一次迭代: 捕获需求, 完成域建模和用例建模(并制定开发计划)。

    第二次迭代: 对关键用例的健壮性分析(Robustness)。
                体系结构设计。
              交互建模。
                建立类模型。
                重要用例的开发及测试工作(通过开篇中红线标注的需求所分析出来的用例)并
                提交可运行的版本。
                完善关键用例模型。

    第三次迭代: 对那些次优先级用例(通过开篇中绿线标注的需求所分析出来的用例)进行分析
                设计和开发,并对第二次迭代的体系结构进行优化调整补充。同时也要去更新类
                模型。并提交可运行的中间版本。

    ...第n次迭代....

    最后迭代 :整体测试,实施,部置安装等。
         
     
    聊到这里今天的文章主要内容都交待完毕了:)  

    最后再将这个阶段经常出现的错误列出来,大家有什么问题可以在回复中进行讨论:)



    十种最常见的绘制时序图的错误

   10. 不为每个用例绘制一个时序图。
         “只有为每个用例中的所有事件流程绘制交互图(在UML中叫时序图)后,才能确定您找
       出系统要求每一个对象扮演的角色,即每个对象的职责。”
                             ---摘自jacobson的<<The Object Advantage>>)

    9. 不将用例文本添加到时序图中。
           将用例的需求级文本放在时序图上提供了可视化需求跟踪,让您在设计时能够参阅经
       用户确定的需求。因为时序图必须同相应用例的叙述式流程一致。

    8. 不首先在健壮性图上确定所有必需的对象。
           如果绘制时序图时有困难,则可能是编写的用例不正确,且/或没有完成健壮性分析。
       有了正确的健壮性图和严格定义的用例后,绘制时序图的工作将容易得多。

    7. 不在用例文本和消息箭头之间提供可视化跟踪。
           应在用例文本中的每个句子和句子片段之间加上一定的空白,使其同对应的消息位于
       同一条水平线上。这将有助于人们阅读时序图时,明白系统将如何完成用例描述的行为。

    6. 不说明对象间的通信管道,让时序图表高级抽象。
           在健壮性图上,无需说明对象间的通信管道,因为它们反映的是初步设计。但编码将
       根据时序图来完成,因此需要极其详细地说明实际的设计方案。

    5. 将时序图绘制成流程图,而不是使用它在对象间分配行为。
           作为分配行为的决策工具。您将使用时序图来分配操作给类,不应使用格式随意的文
       本来标记消息箭头,而应将消息名和类的操作名关联起来。在ICONIX方法中,行为分配(
       决定哪些操作属于哪些类)至关重要,这个阶段的决策决定了总体设计的好坏。

    4. 不将重点放在有趣的方法(实际的软件行为)上,而是放在GET或SET函数上。
           通过研究系统的行为,将知道静态模型中的类需要哪些属性和方法。在决定类在时序
       图中的位置后,就应将相应的属性和方法加入到该类中。但要注意的是,不应在时序图上
       花太多时间绘制所有的getAttribute和setAttribute消息箭头。如果这样做,将达不
     到预期的目标,因为很容易忘记场景的流程。

    3. 不仔细考虑消息箭头的起点(即特定时间内,哪个对象拥有控制权)
           对象之间的消息将调用相应类的操作。虽然在健壮性图中,是否准确地绘制箭头无关
       紧要,但在时序图中必须正确绘制它们,控制流程必须明确,在任何时候,哪个对象拥有
       控制权这一点必须是显而易见的。

    2. 通过绘制消息箭头来分配行为时,不遵循职责驱动的OOD这一基本原则。
           对象(还有类)只能有一种“性格”,应避免对象有“精神分裂症”,这意味着类应
       同一组行为密切相关,即应遵循沿用已久的规则--对象应是高内聚,松耦合。同时还应注
       意其他原则如重用性,适用性等。

    1. 不为每个用例包绘制本地类图,以更新静态模型。
           在域模型中,应确保其中的域类“清洁”,但绘制“本地化”静态类图时,列出解决
       方案空间的对象和问题空间对象是一个不错的主意。相应的指导原则是:对于每一个用例
       包,绘制一个本地类图,这样做即有助于在小组之间分配工作,也可以避免因为静态模型
       过于庞大,无法在一张图中表现出来所造成的问题。

posted @ 2014-05-27 15:38  朗月缠云  阅读(973)  评论(0编辑  收藏  举报