采用[ICONIX] 方法实践BLOG设计之二 [用例建模]

     在上一篇文章中我们了解并进行了域建模,换言之我们有了一个好的开始,起码开发人员对自己
要开发的软件已有了初步的认识,且也得到了进行交流时可以使用的术语表。
     本章将会在前一篇的基本上进一步阐述使用ICONIX方法实践用例建模,同样在文章的最后还会
有在这个阶段最容易犯的10个错误,以给大家提醒或在分析过程中进行参照。
     本文在ICONIX方法中所处的位置如下图(红圈标记的地方)


     在开始进行用例建模之前,我们需要对这一过程有一些粗线条的认识,如果您以前做过或学习过
这方面的知识,可以把下面的内容作为一次温习,如果有不同的意见也可以在回复中进行讨论。
     如果说(问题)域建模结束后得到的是一个静态模型(比如航模或车模)的话,那么要让这个静
态的模型真正动起来的话,我们就需要起动系统行为的动态模型(也就是用例模型)来给这个模型注
入energy(不管是烧汽油还是柴油)。而所谓的动态模型是一种由外到内的分析方式,而域建模是一
种由内向外的方式来分析系统的。有关这个描述所幸直接引用书中的一些原话来说明:
      “域建模过程是一种由内向外”的方式,它意味着将从系统核心对象开始,由内向外工作,确定
这些对象如何参与要构造的系统。而用例驱动(模型的动态部分)是一种由外到内的方法。这就意味
着当您以由内向外和由外到内这两个方向工作时,应使这两部分在途中相遇,而不是让它们不相连。
当进行健壮性分析和绘制时序图时,将完成这项工作”
     看来用例建模是整个驱动(动态部分)过程的起点。而这一过程对于系统的分析又太重要了,所
以在分析开始之前,希望大家再看一下用例的定义,这将对下面的分析起到指导作用。
     我这里直接使用Ivar Jacobson的定义:"用例实例是在系统中执行的一系列动作,这些动作将生
成特定参与者可见的价值结果,一个用例定义一组用例实例
"。(是不是很经典,遗憾的是当初刚看到
这个描述时还不知所云呢:)
     另外,这里需要纠正的两个常识性认识:
     1.用例图不等于用例模型(因为用例模型还包括用例文档)
     2.用例用于分析阶段而不是搜集需求的阶段
     这两个问题相信大家的 UML相关书籍中也看过类似的阐述,所以这里不再另行解释了。


     好了,有了上面的介绍相信以前做过用例建模的朋友或没接触过 UML的朋友对本章节要进行的
实践已有了一个大概的认识。但是如何进行用例建模呢,这里主要分解为三步:
     1.识别参与者(ACTOR)
        参与者作为同系统交互的所有事物,它可以是人也可以是其它系统或硬件等。它不是系统的组
成部分,是独立于系统而客观存在的。其实在确定参与者时可以采用提问的方式来找出来,如谁是系
统的主要用户?谁从系统获得信息等等。而作为BLOG这种软件,这里为了便于分析,将参与者确定
为用户(或会员和作者等,一但确定之后,下面的用例描述就要这样使用它们),同时为了不与域模型
中的用户和用户列表有任何模糊上的关联。这里将域模型中的用户和用户列表更名为用户信息,用户
信息列表。而另一个ACTOR就是系统管理员了,而先前域模型中的系统管理员则相应更名为系统管
理员信息。

     2.确定用例。
     确定用例时ICONIX方法认为“首先要确定尽可能多的用例,然后不断地编写和改进描述这些用
例的文本,在这一过程中,您将发现新的用例和通用情况”。而确定用例的一个最重要的原则就是它
必须同用户手册中的材料密切相关,每个用户和用户指南的各部分之间的关系必须是显而易见的。从
手册出发的原因就是要求开发人员“必须从用户角度来分析和设计系统”。因为手册内容一般都非常
庞大(相关模版在网上获取),动不动就几十甚至几百页。而从中归纳出文档所需要的内容必定也是非
常繁琐的,但这一步又非常必要。因为篇幅所限,又因为担心大家偏离本文的思想,所以这里也只有
跳过了,大家完全可以在网上找到相关的信息来填充这一空白。另外识别用例也可以采用提问方式,
如每个参与者的任务?系统需要何种输入输出?等(详见“系统分析师设计指南之统一建模语言”)。
     在有些书中会使用合并需求(主要是功能性需求,非功能性需求可附加到用例描述中)来获得用
例,而进行合并操作的原则也就是生成“可见结果”的过程 (这一步因为所做的事情过于繁杂,本文
就不再涉略了 ),并完成用例命名和绘制用例图。从我个人来看,这两者(ICONIX方法和其它方法)
是相辅相成,并无冲突。
     限于篇幅直接将初步确定并整理出来的用例列出来[采用动词(短语)-名词(短语)形式]:
     注册用户(UC01),登陆系统(UC02),发表文章(UC03),编辑文章(UC04),删除文章(UC05),
浏览评论(UC07),删除评论(UC08),浏览留言(UC09),删除留言(UC10),添加链接(UC11),
编辑链接(UC12),删除链接(UC13),上传文件(UC14),删除文件(UC15),管理文件类型(UC16),
编辑签名(UC17),编辑个人信息(UC18),编辑BLOG基本信息(UC19),(管理员)审核用户(UC20),
创建俱乐部[或群](UC21)等。
     (管理员的基它功能操作这里只作为次要需求被过滤掉了,希望大家能够理解。从而
将注意力放在ICONIX方法和用例的设计分析上为宜)
     而相关的Blog系统用例图如下(为下面的用例文档细化作准备):
  

     其实要指出一个笔者以前犯过的小错误,相信也是很多朋友不知不觉也会犯的错误,就是如何布置
用例的层次。ICONIX方法建议使用包来展现这种层次结构,举个例子就是管理文章(里面include几个
子用例如添加,编辑,删除文章等),ICONIX会用一个包来包含这几个用例,并写上包的名称,然后再
在包中绘出相应的子图。这样做的原因主要是:
     为开发小组之间分配工作提供了逻辑边界,一条可遵循的规则是每个包对应于用户手册的一间或者
至少一大节。我这里直接用一个大范围用例图的做法主要是为了方便说明整个系统的全貌,使大家对系
统用例有一个整体认识而已。希望大家在实际工作中(用例数量很大的情况下)要进行权衡。
     另外有三种"用例关系"的定义需要在这里简短介绍一下:
     include(包含):
         指一个用例的行为包含了另外一个用例的行为,这是一种特殊的依赖关系。也就是"has a"的关
         系。见上图中的(管理文章和发表,编辑以及删除文章的关系)
     generation(泛化):
         指一个用例(子用例)继承另外一个用例(父用例)的行为和含义,而该用例在继承了另外一个
         用例的行为和含义的基本上,还可以增加新的行为和含义以覆盖原有用例的行为和含义。比如
         “按作者进行BLOG检索”和“按内容进行BLOG检索”与“BLOG检索之间”的关系。这种关系
         可以用"is a"来表示。
     extend(扩展):
         类似于泛化(generation)关系, 不过对扩展的用例有更多的限制。如一个用例明显地混合了两
         种或以上的不同场景,即可能发生多种事情。而我们可以断定将这个用例分为一个主用例和一个
         或多个辅用例描这可能更加清晰。

     好了,有了用例之后就该细化用例文本了。

     3.细化用例文本。
     首先先拿用户注册开刀。假设用户文本如下:

     用例名称:注册用户(UC01)
     用例文档:
     基本流程:
          用户输入其姓名,密码(两次),EMAIL地址,然后点击注册按钮。系统在确认该用户提交信息
     有效之后,使用当前数据初始用户相关信息并记录到用户信息列表中。然后系统提示用户要等待系
     统管理员进行审核。

     分支流程:
          如果用户没有提供姓名,系统将显示一条错误信息,来告之用户输入姓名。
          如果用户提供的EMAIL地址格式不正确,系统将显示一条错误信息, 要求用户输入正确的EMAIL
     地址。
          如果用户两次输入的密码不同,系统将显示一条错误信息,提示用户两次密码要一致。
          如果用户提交的用户名已在用户信息列表中存在,系统将告诉用户并建议用户使用其它的用户名。

     可能大家看到之后,有些人会认为这一步过于简单了,因为在不少介绍用例的书里当讲到这块都会
长篇大论一番,并且关于如何描述用例子的基本和分支流程有些 UML书籍可能会提供一些可参考的规
则如:
     1.主语名称,语义要易于理解
     2.要让读者明确参与者在控制还是系统在控制。
     ....

     而作为ICONIX方法中的用例模版,它与其它的 UML方法或许多大师级所推荐使用的用例模版有所
不同。它用的是1040EZ式模版,换言之它所主要包括的是基本流程 (基本事件流)和分支流程 (扩展事
件流)。它不像复杂的模版中还要有前置,后置条件,非功能性需求,扩展点和优先级等内容。该方法认
为那些东西不仅会分散注意力同时也会浪费宝贵的时间。

     作为ICONIX它所推荐的做法是:
     1.创建简结的用例模版(其中标有“基本流程”和“分支流程”)
     2.提出“将发生什么” 的问题,然后进行基本流程
     3.提出“然后将如何”,并不断提出这样的问题,直到你获得有关基本流程的所有细节
     4.提出“否则将如何”,是否还有其它情况? are you sure? 不断提出这些问题,直到记录下来大
量分支流程为止

     总之这么做不求完美无缺,而是考虑用户可能执行的操作。
     大家可以参考这些规则来看上面的"注册用户"看看是否还有什么别的启发:)
     另外需要要强调的就是用例文本基本形式:名词-动词-名词

     “同时这一过程中如果发现新的对象后,还应对(问题)域模型进行更新,来加深对以前发现对象
的理解”。(比如我们将在下一个用例中发现新的对象)
 
     下面说一个用例就是“管理文章”用例的三个子用例,大家在这里看到它包含三个子用例,分别是发
表,编辑和删除文章,而有关包含(include) 上面已做过说明。它自身的三个子用例是系统的主要功能。

     用例文档:
   
     发表文章(UC03)
     基本流程:
          用户在发表文章页面中输入文章标题,所属分类(自定义或系统类型),文章内容,是否使用摘
    要,是否发表(或放入草稿箱)等信息之后点击提交按钮,系统在确认该篇文章提交信息有效之后,
    使用当前数据添加到文章列表中。

     分支流程:
          如果用户没有文章标题,系统将显示一条错误信息,告之用户输入文章标题。
          如果用户提供文章内容,系统将显示一条错误信息, 要求用户输入文章内容。
          如果用户采用摘要形式发布,但却没有录入摘要内容时,系统将显示一条错误信息, 要求用户输
    入摘要内容。
          如果用户在未完成当前文章内容时要跳转到其它页面,系统将显示一条警告信息,提示用户所编
    辑的内容将会丢失。
          如果用户提交的文章标题已在文章列表中存在,系统将告诉用户并建议用户使用其它的标题。


    编辑文章(UC04)
    基本流程:
         用户在编辑文章页面中修改文章标题,所属分类(自定义或系统类型),文章内容,是否使用摘
    要,是否发表(或放入草稿箱)等信息之后点击提交按钮,系统在确认该篇文章提交信息有效之后,
    使用当前数据修改文章列表中的相应文章信息。

    分支流程:
         如果用户没有文章标题,系统将显示一条错误信息,告之用户输入文章标题。
         如果用户没有输入文章内容,系统将显示一条错误信息, 告之用户输入文章内容。
         如果用户采用摘要形式发布,但却没有录入摘要内容时,系统将显示一条错误信息, 要求用户输
    入摘要内容。
         如果用户在未完成当前文章内容时要跳转到其它页面,系统将显示一条警告信息,提示用户所编
    辑的内容将会丢失。
         如果用户提交的文章标题已在文章列表中存在,系统将告诉用户并建议用户使用其它的标题。



    删除文章(UC05)
    基本流程:
         用户在文章列表页面上点击相应文章标题左侧的"删除"按钮后,系统提示用户是否删除该标题的
    文章,当用户确认后则删除文章列表中的相应文章内容信息。

     分支流程:
          如果用户在提示框中点击"取消删除"按钮,则系统将不会进行任何操作并将页面重定向到文章列
     表页。


     在上面三个用例文本中都提到了一个新的对象就是文章列表,而这个对象是我在上一篇文章中提到但
没加入到域模型中,而这里因为从需求中得到了系统确定需要这个对象,所以需要更新一下相应的域模型
了:)
   
     下面要说的一个用例就是"管理文件类型"。
     在聊这个用例之前有些问题需要先解释一下,就是这个用例本身是否需要分解为三个子用例(添加,
编辑,删除)会更为合适? 但是如果这样做的话,就会使得用例的数目多添加三个。如果说一遇到这种情
况就去如此分解的话,可能会使用例的数目过于庞大。这其实也是一个需要注意的问题,在许多用例驱动
的书中都肯定会不可避免的谈到这一问题,即“用例的分解粒度”,因为分解过度会显著提高复杂度,而
过低则有可能违背用例的“可见价值结果”的原则。如果说“管理BLOG系统”这个用例就是一个太大的
用例,根本看不出什么对用户有价值结果。而“输入用户名”这个用例又太小,把它当成一个步骤会更合
适,这个“度”上的把握最终还是要从系统(软件)的整体来衡量才是根本。
     聊了这么一大堆再回到当前的"管理文件类型"这一用例上,在我看来,它本身可能是因为用户(文档)
比较简单所以就把三个所谓的子用例做了一下合并,变成一个用例。当然这也是仁者见仁,智者见智,不
是完全绝对化的,还希望大家自行斟酌,多提意见:)

    
    管理文件类型(UC16)
    基本流程:
         系统管理员在"添加文件类型"表单中(位于"文件类型列表"页面)输入文件类型名称(如RAR,JPEG
    等),类型描述,最大上传尺寸,上传路径名称等信息之后点击提交按钮,系统在确认该信息有效之后,
    使用当前数据添加到文件类型列表中。
         系统管理员在文件类型列表页面中的相关类型上点击删除按钮,系统提示是否删除该文件类型,在
    管理员确认后则从文件类型列表中删除相应的记录。
         系统管理员在编辑文件类型页面中修改相应类型名称,类型描述,最大上传尺寸, 以及相应路径后
    点击更新按钮,系统在确认该信息有效之后,使用当前数据修改类型列表中的相应文件类型信息。
   
    分支流程:
         如果用户在添加和编辑表单中没有输入类型名称,最大上传尺寸,上传路径名称时系统提示输入相
    关信息。
         如果用户提交的类型名称已在文件类型列表中存在,系统将告诉管理员并建议管理员使用其它的名
    称。
         如果用户在提示框中点击取消删除按钮,则系统将不会进行任何操作并将页面重定向到"管理文件类
    型"页面。

    在这里同样也发现了一个对象就是“文件类型列表”,也把它放入到域模型中去吧:)
    (我想这个用例大家肯定会有不同意见的,欢迎在回复中进行讨论。)

     而其它的用例文本因为本人时间有限,未能全部打出来,我会在将来抽时间尽力完善其中内容,希望大
家谅解。必定本文探讨的是对ICONIX方法的实践,所以主要还是要将这一方法在分析用例时所使用的技巧
和步骤写出来才是本人写这个系列文章的主要目的。

     最后还是例行公事将十个最常见的用例建模错误列出来,如果大家认为哪个错误说的不太清楚,可以告
诉我,我会将相应的解释放在下面,以便大家进一步去讨论。

       
    十个最常见的用例建模错误:
    10.编写功能性需求,而不是编写使用场景文本。
     9.描写属性和方法而不是使用情况。
     8.编写用例过于简洁。
     7.让自己和用户界面完全脱离。
     6.不给边界对象提供明确的名称。
     5.不从用户的角度进行编写,并使用被动语态。
     4.只描述用户交互,而忽略系统作出的响应。
     3.不描述操作的分支流程文本。
     2.不将重点放在用例内部,而是放在如何到达这里或以后将发生的情况。
     1.花一个月的时间来决定使用包含结构(include)还是扩展结构(expand)。

     相关ROSE文件下载链接:用例建模(rose文件)
     最后声明:由于本人水平有限,且本文涉及的知识点又过多且非常繁杂,因此文中难免有不妥和错误之
处,诚恳园子里的朋友和高人不吝赐教和帮助,对此我将深表感谢:)

     关键字:ICONIX,UML,USE CASE,用例,OO,面向对象,用例驱动。
posted @ 2007-10-09 12:22  代震军  阅读(6478)  评论(26编辑  收藏  举报