用UML进行面向构件分析与设计

1       用例分析

用例方法首先描述了系统有哪些外部参与者(抽象成为Actor),这些参与者与系统发生交互;针对每一参与者,用例方法又描述了系统为这些参与者提供了什么样的服务(抽象成为Use Case),或者说系统是如何被这些参与者使用的。所以从用例图中,我们可以得到对于系统的一个总体功能的集合。

 

与传统的功能分解方式相比,用例方法完全是从外部来定义系统的功能,它把需求与设计完全分离开来。用例定义了系统功能的使用环境与上下文,每一个用例描述的是一个完整的系统服务。用例方法比传统的功能分解方法更易于被用户所理解,它可以作为开发人员和用户之间针对系统需求进行沟通的一个有效手段。

1.1    寻找参与者(Actor)

参与者是指所有存在于系统外部并与系统进行交互的人或其他系统。通俗地讲,参与者就是我们所要定义系统的使用者。寻找参与者可以从以下问题入手:

l        谁使用系统的主要功能?

l        谁负责处理流程中的环节?

l        谁从系统获取信息?

l        谁负责维护、管理并保持系统正常运行?

l        系统需要和哪些外部系统交互?

 

有时候我们需要在系统内部定时地执行一些操作, 如当任务到达时自动发送通知短信、当任务超出处理时限自动发送催办通知、定期地生成统计报表等等。从表面上看,这些操作并不是由外部的人或系统触发的,应该怎样用用例方法来表述这一类功能需求呢?对于这种情况,我们可以抽象出一个系统时钟或定时器参与者,利用该参与者来触发这一类定时操作。

 

以派发故障单环节为例,故障派单人负责使用派单功能,因此需要派单人这个参与者。经过对某故障处理流程各环节的分析,我们识别出以下参与者:

 

 

 

1.2    寻找用例(Use Case)

找到参与者之后,我们可以根据参与者来确定系统的用例。主要是看各参与者需要系统提供什么样的服务,或者说参与者是如何使用系统的。寻找用例可以从以下问题入手(针对每一个参与者):

l        参与者是否在系统中创建、修改、删除、访问、存储数据?

l        参与者如何驱动流程的流转,对流程中的环节进行了哪些操作?

l        参与者是否会将外部的某些事件通知给该系统?

l        系统是否会将内部的某些事件通知该参与者?

 

在用例的抽取过程中,必须注意:用例必须是由某一个参与者触发而产生的活动,即每个用例至少应该涉及一个参与者。如果存在与参与者不进行交互的用例,就可以考虑将其并入其他用例;或者是检查该用例相对应的参与者是否被遗漏。反之,每个参与者也必须至少涉及到一个用例,如果发现有不与任何用例相关联的参与者存在,那么该参与者可能是一个多余的模型元素,应该将其删除。

在用例建模过程中必须注意参与者和用例的名称应该符合一定的命名约定,如参与者的名称一般都是名词,用例名称一般都是动宾词组等。

用例分析就是分析什么人做什么事,描述做事要描述详细到什么程度呢?这就是粒度问题。一个用例的粒度是否合适,是以该用例是否完成了参与者的某个目的为依据的。举个例子,某人去图书馆,查询了书目,出示了借书证,图书管理员查询了该人以前借阅记录以确保没有未归还的书,最后借到了书。从这段话中能得出多少用例呢?用例分析是以参与者为中心的,因此用例的粒度以能完成参与者目的为依据。这样,实际上适合用例是:借书。只有一个,其它都只是完成这个目的过程。现实情况中,一个大型系统和一个很小的系统用例粒度选择会有一些差异。这种差异是为了适应不同的需求范围。一般来说,一个系统的业务用例定义在多于10个,少于50个之间,否则就应该考虑一下粒度选择是否合适了。

对于同一个系统,不同的人对于参与者和用例都可能有不同的抽象结果,因而得到不同的用例模型。我们需要在多个用例模型方案中选择一种"最佳"(或"较佳")的结果,一个好的用例模型应该能够容易被不同的涉众所理解,并且不同的涉众对于同一用例模型的理解应该是一致的。

以派发故障单环节为例,参与者“故障派单人”需使用派单功能,来完成对故障工单派发的目的,因此形成派发故障单这个用例。

经过对某故障处理流程各个环节的分析,我们抽取出以下用例:



 

 

 

 

以上的用例模型,除了从流程环节功能分析得到的用例外,还有一部分是从通用功能角度分析而来的,如:查看日志,查看流程图等等。

1.3    用例分析与功能分解矩阵

经过以上分析获得的用例模型,一方面是用标准的需求分析方法对流程环节的功能进行了描述,另一方面也为我们进行下一步骤的功能分解打下了扎实的基础。

在建设用例模型的过程中,我们以流程名称建立一级包名,以环节名称建立二级包名,如下图所示:

 

 

 

在将用例模型映射到功能跟踪矩阵的过程中,一般的规则是:一级包名映射到一级模块,二级包名映射到二级模块,用例名称映射到三级模块。以用例模型为基础,我们将用例包名和用例名称映射到功能跟踪矩阵中,得到如下的功能跟踪矩阵:



 

 

 

2       分析模型

我们是通过对用例的分析,从而形成分析模型(Analysis Model)来完成分解的工作的。

分析模型采用MVC模式,在系统架构和框架的约束下,来分析用例的实现的。在分析过程中,将使用UML的语言来描述系统中的人、事、物、规则(actor,boundary,engity,control)之间的交互和动作的。通过使用UML的时序图将是将用例中所包含的业务处理流程表示出来,一方面能够对功能进行粒度较细的分解,另一方面又能有效的指导设计与实现。

 在分析工作中,有以下主要的产出:

分析类 业务领域中建模的主要概念,代表了系统设计中的类或子系统的抽象。分析类代表“系统中具备职责和行为的事物”的初期概念模型。这些概念模型最终将演进为设计模型中的类和子系统。

用例实现 演示分析类的实例如何交互以实现由用例所说明的系统行为。用分析类及交互图(协作图、顺序图)来表示。

2.1    寻找分析类

分析类的构造型可分为以下几种: 边界类 (Boundry Class)、控制类 (Control Class)、实体类(Entity Class)

边界类是一种用于对系统外部环境与其内部运作之间的交互进行建模的类。这种交互包括转换事件,并记录系统表示方式(例如接口)中的变更。

控制类用于对一个或几个用例所特有的控制行为进行建模。控制对象(控制类的实例)通常控制其他对象,因此它们的行为具有协调性质。

实体类是用于对必须存储的信息和相关行为建模的类。实体对象(实体类的实例)用于保存和更新一些现象的有关信息,例如:事件、人员或者一些现实生活中的对象。

考虑参与者“故障派单人”执行用例“派发故障单”这个场景。用MVC的模式对该用例进行分析:故障派单人需要在某个界面上(边界类),录入故障信息,然后提交给业务逻辑处理(控制类);业务逻辑负责保存故障工单信息(实体类)。经过对用例“派发故障单”的分析,我们得到以下的分析类:



  



2.2    用例实现

用例实现是描述如何在设计模型内部利用协作对象来实现一个特定的用例。对于每个用例,都可以用一个或多个交互图来描述它的参与对象以及它们之间的交互。多数情况下,我们使用序列图来说明对象如何通过交互来执行全部或部分用例的行为。

序列图对设计人员特别重要,因为它们明确了构件在调用流程中的角色,因而可以为确定构件的责任和接口提供基本的输入。

通过对用例“派发故障单”的分析,我们绘制作了以下的顺序图:




 
 

 

 

可以看到,顺序图是以交互为主线,将交互过程中各交互对象识别出来,并由上至下、从左到右,以时间发送为序,将交互关系表示为一个二维图的。纵向是时间轴,时间沿竖线向下延伸。横向轴代表了在协作中各独立交互对象。

2.3    分析模型与EOS构件

绘制出上面基本的顺序图之后,我们还需针对“派发故障单业务逻辑”进行细化。将业务逻辑中的处理操作的步骤分析出来,将其中的操作分散在各构件包中,并将构件包调用关系在顺序图上描绘出来。

 在这里我们先对构件包的概念和分包的原则进行阐述。

EOS构件包是由六种构件(业务构件、展现构件、页面构件、数据构件、运算构件、工作流构件 )(或者其中的几种)组成,是EOS系统发布、复用的基本单位,它由一组相关的EOS构件组成,能够完成相对独立、完整的业务功能。EOS构件包中可以包含一个或多个的EOS构件,它相当于一组有关系的构件的容器或命名空间(Namespace)

构件包分包原则:

1.相关性:从应用功能维度上,每个构件包实现了一组具有相关性的业务功能。在划分构件包过程中,始终要考虑在构件包中的构件在业务上是否有相关性。如对工单(数据或流程)的一系列操作,从业务角度看,是具有高度的相关性,因此可以形成一个工单构件包。

2.公共性:实际上构件包可以理解为业务功能分解后的功能模块。对业务功能分解之后,往往能抽取出一些具有公共性的操作,比如附件管理、记录日志、查询待办工单等等。这些操作不直接与业务相关,但能提供给业务流程各个环节中复用。因此可以形成一个通用构件包。

根据对某故障流程的分析,按照业务功能相关性的原则,我们将业务逻辑分为以下五大构件包:

工单构件包:提供与故障工单相关功能的一组构件包,例如:设置工单状态,获取故障工单信息,获取工单处理情况等等;

任务单构件包:提供与任务单相关功能的一组构件包,例如:设置任务单状态,分派任务单,保存任务单等等;

通用构件包:提供在其他构件包调用到的通用功能的一组构件包,例如:上传附件,管理附件权限,发送短信,保存工单时限设置等等;

接口构件包:提供与接口解析相关功能的一组构件包,例如:自动派单,半自动派单,草稿生成工单,告警工单处理状态实时通知等等;

统计构件包:提供与KPI相关功能的一组构件包,例如:统计故障处理及时率,统计故障一次处理完成率,统计故障一级解决率等等。

对于同一个系统,不同的人对于构件包分包都可能有不同的拆分结果。我们需要在多种分包方案中选择一种"最佳"(或"较佳")的结果。一个好的分包方案应该能够容易被业务分析人员、系统设计人员及系统开发人员等所理解。

针对“派发故障单业务逻辑”,我们进行再次分析,结合流程特点和业务功能,重新绘制新的顺序图,将派发过程中 “工单构件包”、“通用构件包”等协作交互表达出来。首先,在请求派单阶段,系统在显示派单信息录入界面,需要自动匹配告警监控网管信息和告警级别;其次,如果派单人在派单界面上进行“抄送”操作,系统需要显示抄送人员列表供其选择;再次,如果派单人进行“上传附件”操作,系统需要提供附件上传功能;最后当派单人选择提交派单, 系统将调用工单构件包中的保存故障单信息功能构件,在此保存故障单信息的过程中,还需调用通用构件包中的获取工单时限设置、获取工单派单对象,完成保存后还需调用完成工作项、设置流程活动的参与者、设置流程的流转条件等。

 

如下图所示,在派发故障单过程,我们经过分析抽取出以下细粒度的功能:匹配告警监控网管信息、映射网管告警级别 、获取抄送人员 、上传附件 、保存故障单信息 、获取工单时限设置 、获取工单派单对象 、完成工作项 、设置流程活动的参与者 、设置流程的流转条件。

 



 


 

 

 

根据“派发故障单”的用例实现顺序图,我们将顺序图上的操作功能映射到功能跟踪矩阵。映射的一般原则是,由界面(派发故障单页面)开始的操作功能映射为功能点,如“获取抄送人员”,“上传附件”等;由构件包(工单构件包、通用构件包等)开始的操作映射为功能分解,如“获取工单时限设置”、“获取工单派单对象”。映射完成的功能跟踪矩阵,如下图所示:

 

 

 

这样我们经过用例分析,和用例实现分析,逐步细化的得到了系统功能跟踪矩阵。

对所有的用例进行分析,并绘制出顺序图之后,我们将获得如下构件包图:

 



 

 

以上的构件包图,共有五个构件包,每个构件包中都包含若干个操作功能,每一个操作功能都可以映射成一个独立的业务处理逻辑构件。这些构件涵括了某故障流程各环节中处理的功能。以该用例模型为基础,能有利于我们形成功能分解矩阵,也能有利于我们识别可复用构件。      

更多文章,请访问: http://gocom.primeton.com/blog_26961.htm

你可能感兴趣的:(设计模式,mvc,活动,领域模型,UML)