您好,欢迎来到爱玩科技网。
搜索
您的当前位置:首页一个例子说明UML及系统分析withEA实作

一个例子说明UML及系统分析withEA实作

来源:爱玩科技网
一个例子说明UML与系统分析

1. 案例场景描述

3.1.1 仁医院案例背景描述

在HSDc的RA与信仁医院的特助及用户经过一到两次的需求访谈后,HSDc的软件架构师(Software Architect)请他们的项目经理(Project Manager; PM)安排了一次跟信仁医院特助的访谈。

信仁医院的特助觉得很不可思议,因为他完全不懂软件的设计,也没有写过程序,在他以往的经验中,也只和其他软件公司的系统分析师(System Analyst; SA)进行过访谈。在他的想象中,软件开发人员的对等窗口应该是医院的信息中心,似乎不大应该是他,HSDc的项目经理特别跟信仁医院的特助说明,他们的软件架构师主要是要了解一下信仁医院的领域模型(Domain Model),因此希望和信仁医院中的领域专家(Domain Expert)来沟通。

信仁医院的特助抱着有些怀疑又有点好奇的心态,参与了这次的访谈,以下是该次访谈的部分内容。

HSDc项目经理:特助,今天非常谢谢你百忙之中抽空来参加这次访谈,接下来我把时间交给这次项目的软件架构师。

信仁医院特助:别这么说,其实我也很好奇,希望可以帮助你们软件人员些什么,毕竟,我对软件开发一窍不通。

HSDc 软件架构师:特助,不要这么说,我们才是医院相关业务的新手,我想能够有机会和你谈谈,对于未来我们在进行软件设计时,有相当大的帮助。

信仁医院特助:哦,是这样啊,那我们要怎么开始呢?

HSDc 软件架构师:嗯,首先,我想要了解一下,在贵单位的住出院业务中,有什么样的\"事件\"是特别重要的,需要被记录下来的。

信仁医院特助:所谓的\"事件\"指的是什么?

HSDc 软件架构师:举个例子来说,像病人来医院看病时,必须要先到柜台去做一个登记,这个登记的动作必须被医院记录下来,以利后续的处理,这个事件在医院就称为\"挂号事件\"。总之,所谓的\"事件\"指的是其发生于某一个特定的时间点,且对于后续某些业务会有相对影响的业务。

信仁医院特助:嗯,我好像有一点了解了,\"事件\"?还蛮有趣的。

HSDc 软件架构师:哈哈,软件就是这么有趣啊!

信仁医院特助:好,让我想一想……有了,住出院业务应该会有一个重要的事件:住院,这是所有业务的一个起始点。

HSDc 软件架构师:嗯,非常好。接下来我要请问的是,\"住院事件\"本身需要记录些什么?有没有需要什么相关的明细信息?

信仁医院特助:我不大懂。什么叫做\"明细信息\"?

HSDc 软件架构师:让我再举一个例子。特助有到书店买过书吗? 信仁医院特助:当然有。

HSDc 软件架构师:那我就以买书作为一个例子来说明。在买书时,对书店来说,必须要记录一个\"顾客买书事件\"。

信仁医院特助:对。

HSDc 软件架构师:可是顾客买的书可能超过一本,这时候,书店的\"顾客买书事件\"中,就必须要记录顾客买了哪些书的\"明细信息\"。

信仁医院特助:哦,我知道了。那就是我们之前跟其他软件厂商谈的时候,他们老是挂在口中的什么\"一单多料\"、\"Master-Details\"什么的。说实话,我真听不大懂他们在说什么。

HSDc 软件架构师:哈哈,这是软件人员常常会犯的一些错误,真地很抱歉哦!回到我们的问题,对于医院的\"住院事件\"来说,有没有什么明细信息是需要保存下来的?

信仁医院特助:我想想。病人的数据?这是明细信息吗?

HSDc 软件架构师:病人的数据?是每一次不同的住院事件,病人的数据都会不同吗? 信仁医院特助:那倒不是。

HSDc 软件架构师:那就不是明细信息了。病人的数据倒比较像是参与这次\"住院事件\"的关系人。

信仁医院特助:哦。那病人这次住院的病情信息呢?

HSDc 软件架构师:嗯,这听起来就有点像了。不过每一次的住院事件中,会有多个的病情信息吗?

信仁医院特助:嗯,有可能。病人可能是因为内科诊断需要住院,但是需要其他科别的会诊。

HSDc 软件架构师:很好,那我们找到了明细信息及相关征状的信息。接着,我要请问的是,对于我们医院的工作人员来说,住院事件有哪些人员会参与?

信仁医院特助:有医生、护士,还有柜台人员等。

HSDc 软件架构师:了解了。我记得好像住院的时候有分主治大夫跟住院医生,这两个角色的人对于住院事件的处置会有所不同吗?

信仁医院特助:嗯,大体来说,两个角色都要直接对病人负责,不过主要的病情判断还是由主治大夫来负责,住院医生只是担任紧急状况的紧急处置。

HSDc 软件架构师:所以对于一个住院事件来说,主治大夫跟住院医生是各有一个喽! 信仁医院特助:原则上是这样。

HSDc 软件架构师:对了,我记得以前在SARS(非典型肺炎)时,好像有听说有些医院因为没有\"负压隔离病床\",所以不能够接SARS的患者,那是不是代表在住院的时候,特定的病床会给特定的疾病来使用?

信仁医院特助:我们医院没有这个问题。当然,原则上病床有分为各科别各自的病床,不过这并非强制性的,外科的病人有时也可以住进内科的病床。但是既然提到这个问题,让我想到跟医院经营相关的问题。原则上,我们的病床分成两类,一类是医保病床,这类型的病床,病人不需要负担病床的费用;另一类的病床则是非医保的病床,这类型的病床,病人则需要部分负担病床的费用。未来在结算病人住院的费用时,我们需要知道病人究竟是使用哪一种病床。

HSDc 软件架构师:太好了,这对我们的设计有很大的帮助,谢谢。我想今天的会议到这边应该可以先告一段落,再次感谢特助的帮忙。

信仁医院特助:就这样啊?不用谈什么表单吗? HSDc 软件架构师:不用,这样就可以了。

2. 问题与分析

3.1.2 问题与分析

在前述的场景中,揭露了软件的几个主要特质。在HSDc的软件架构师与信仁医院特助的对谈过程中,其实隐含了相当多对于软件本质的一些讨论。

先看一下这段对话: 对话分析

HSDc 软件架构师:嗯,非常好。接下来我要请问的是,\"住院事件\"本身需要记录些什么?有没有需要什么相关的明细信息?

……

信仁医院特助:哦,我知道了。那就是我们之前跟其他软件厂商谈的时候,他们老是挂在口中的什么\"一单多料\"、\"Master-Details\"什么的。说实话,我真地听不大懂他们在说什么。

这一段对话中,揭露了软件人员在面对客户时,常犯的一个错误:用太多的专有名词(而且是自己发明的专有名词,像Master-Details等UI的呈现说明)跟客户沟通,而忽略了本质性的讨论。

HSDc的软件架构师想要知道的是事件本身的明细信息,这跟如何呈现其实并没有关系,然而由于信仁医院的特助以往与软件人员的接触中,有许多\"不大美好\"的经验。因此,反而不知道HSDc软件架构师究竟想要什么。这似乎有些\"倒果为因\",由于对软件人员的\"满嘴专业术语\"有些抗拒,在回到事情的本质时,反而有些不习惯。

事实上,套用一句Nokia著名的广告语(slogan):科技以人为本,软件也是一样。软件的结构若脱离了\"事物的本质\",其实就已经失败了一半。这也是为什么许多的软件设计的书籍(甚至连结构化分析设计),都那么重视\"本质\"(essential)的原因。

那么,\"本质\"究竟是什么?

正如同前一节中的场景描述,\"本质\"指的就是要想办法直指想要解决的问题的\"核心\"。 从流程的观点来看,本质就是前一章中所谈的\"事务流程\"的抽象化呈现;而从软件结构面来看,本质指的则是你所要解决的问题领域(problem domain)中的重要\"概念\"(concept)在抽象(abstraction)层次的呈现。一般来说,这样的呈现方式,会通过\"概念模型\"(conceptual model)来表示。

何谓\"概念模型\"呢?其实就是能够用最简化的方式表达一个完整的\"问题领域\"的抽象表示法。举例来说,孔子的学生问孔子,他的中心思想是什么?孔子说:\"吾道一以贯之\",就是一个\"仁\"字。

\"仁\"就是孔子表达其所有思想的一个\"概念模型\"。所以,在《论语》一书中,\"仁\"字出现了109次,孔子每一次都用不同的方式来解释\"仁\",这就代表了\"仁\"这个抽象概念,有至少109种的\"体现\"方式。

相同地,软件也有各种不同的抽象表达法。传统的\"结构化分析设计\"(Structured Analysis and Design)使用\"数据流图\"(Data Flow Diagram; DFD)来表达软件的结构,其重视的主要是数据与数据之间的\"处理程序\",这虽然贴近了商业处理的逻辑,但却忽略了\"问题领域\"的概念。

正如我们前面所说,\"概念模型\"是\"问题领域\"的一种抽象化呈现模式,因此,在设计\"概念模型\"时,务必先把\"问题领域\"定义清楚。举例来说,我们要表达\"医院内部如何处理住出院\"的问题领域,那就需要先把这个问题领域中一些重要的\"元素\"(element)先抽象出来。\"数据\"只是这些元素的其中一种表现方式,因此,我们可以把\"数据\"视作是找寻\"概念模型\"的参考,并不能把它当做是\"概念模型\"本身。

那么,如何找寻需要的\"概念\"呢?针对你所关心的问题领域,重要的概念不外乎\"人、事、时、地、物\"这5个方面。因此,想办法把这5个方面找出来,并且把它们之间的关系构造起来,就成为找出\"概念模型\"的最佳实务。

所谓的\"类\"(Class),其实就是对于前述概念的一种\"分类方式\",由于\"概念\"本身要呈现多种的\"抽象\"含义,UML中的类图,也是这13张UML图形中最复杂的(就好像孔子说的\"仁\",到了现在,还是很多人不知其所以然)。

3. 类图的基本认识

3.1.3 类图的基本认识

类图可以说是整个开发过程中最重要的一个产物。通过类图,我们可以了解设计人员对其所面对的领域(Domain)的想象(Conceptual Model),进而了解设计人员在设计上的一些重要设计(Interface、Abstract及Design Pattern 的应用)的表达与观点。

事实上,由于类图的存在,设计的想法才有可能完整表达,并且可以把这些想法确实保存下来。有经验的设计人员,可以通过类图掌握其他设计人员对于系统的看法,而没有经验的设计人员,也可以通过类图进行学习。因此,无论是何种系统的开发,类图是UML 13 张图中最有必要保存的一张图。

图3-1是设计人员针对医院的门诊系统所设计的类图:

图3-1 某医院门诊系统的类图 相同地,我们通过该张图来认识类图中的一些重要的元素。

类(Class)

类图中最重要的元素就是类(Class)。类主要是由名称(Name)、属性(Attribute)及操作(Operation)所组成。

属性主要是类的某些重要的特性,这通常是属于\"数据面\"的一些描述;操作则是类可以运作的一些\"行为\"(Behavior)。

类的表达方式为:

关联(Association)

类与类之间最基本的关系就是关联。

关联表达了两个类所规范的对象彼此间的结构性关系。以图3-1而言,诊断与医生类间有一个关联,这就代表着\"某一个诊断的事件\",一定会有\"某一医生\"来参与。

关联的图示为。

泛化(Generalization)关系

泛化(Generalization)关系表达了两个类间的\"一般\"与\"特殊\"的关联性。一般来说,通常会为了增加系统的弹性而设计泛化关系。

泛化的图示为。

整体-部分(Whole-Part)关系

整体-部分(Whole-Part)关系是关联的一个特例,因此,整体-部分关系其实也是属于结构性的关系。

一般来说,针对整体-部分间不同的强度,整体-部分关系又分为 \"聚合\"(Aggregation)及\"组合\"(Composition)两种关系。

聚合的图示为:;

而组合的图示则为:。

依赖(Dependency)关系

依赖(Dependency)关系是一种使用的关系,依赖关系的两个类并没有结构性的关联性,一般称之为\"弱相关\"。

依赖关系的图示为:。

多重性(Multiplicity)

多重性(Multiplicity)通常在\"关联\"或\"整体-部分\"关系中会加以使用,代表着对象关系结构中彼此能够允许的最少及最大的数量。

举例来说,一辆车子最少必须要有4个轮胎,最多可能有8个轮胎,那么,车子跟轮胎间的多重性就是4~8。

其表示法为:。

4. 住、出院系统的领域模型

3.1.4 信仁医院住、出院系统的领域模型

\"概念模型\"的原始定义是表达问题领域中的抽象概念。因此,通常也可以把概念模型称为\"领域模型\"(Domain Model)。

领域模型的表达方式非常多,如同前文所说的\"数据流图\",也是一种表达领域模型的方法。除此之外,如在表达数据库设计的\"实体-关系模型\"(Entity-Relationship Model; E-R Model),也是表达领域模型的另一种设计图形。

在UML中,通常会建议使用\"类图\"(Class Diagram)作为表达领域模型的图形。由于类图中,同时表达了某一个特定的实体(Entity,或称为对象(Object))的属性(attribute)与行为(behavioral),可以让领域模型充满层次感。至于找出领域模型的方法,其实非常多。若针对一般\"管理信息系统\"(Management Information System; MIS)领域的模型,通常建议可以利用\"事件\"作为核心,找出与事件相关的\"人、地、物\",并让其有一个遵循的标准。

这样的方式,其实是Peter Coad在《Object Models - Strategies, Patterns, & Applications》一书中所介绍的\"交易模式\"(Transaction Patterns)。有关交易模式的详细说明,我们将在\"第2篇:UML与软件开发实战\"进行介绍。

在前述的场景中,HSDc的软件架构师,其实就是利用交易模式作为基础,通过访谈把信仁医院住出院系统的领域模型找出来。根据访谈记录,信仁医院住出院系统初步的领域模型,如图3-2所示:

图3-2 信仁医院住出院系统的领域模型 有兴趣的读者可以比较一下前面所叙述的场景与图3-2的关系,试着画画自己的领域模型。

5. 在EA中绘制类图

3.1.5 在EA中绘制类图(1) Step 1:选择放置类图的位置。

请在ch03-example.EAP中的\"Model → Domain Model→信仁医院住出院系统\"下新建一张\"Class Diagram\",命名为\"信仁医院住出院系统\"。

图3-3 新增一张\"信仁医院住出院系统\"的Class Diagram Step 2:绘制\"住院事件\"类。

接下来,请先绘制一个类。一般来说,在领域模型中第一个绘制的类,通常是一个\"核心类\",也就是说,该类未来会连接到许多其他的类。

以信仁医院住出院系统的例子来说,这个类就是\"住院事件\"类。

(点击查看大图)图3-4 绘制一个\"住院事件\"的类 UML名词解释

构造型(Stereotype)

《The Unified Modeling Language User Guide》一书对Stereotype的定义如下: stereotype A extension of the vocabulary of the UML, which allows you to create new kinds of building blocks that are derived from existing ones but that are specific to your problem.

也就是说,stereotype是用来扩展原来的UML图形,使其符合我们问题领域的定义。 在图3-4中,笔者使用一个\"Transaction\"的stereotype来表达该类是属于\"交易模式\"定义中的\"Transaction\",这可以让设计人员望文生义,了解该\"住院事件\"本质上的一些不言可喻的特性。

在图3-4中,使用了EA的一个特殊字段\"别名\"(alias),可以让设计人员在设计类时用英文来命名,但是在类图中呈现中文的命名。

图3-4的设计完成后,在EA中的呈现应如图3-5所示:

图3-5 未使用别名的类图 请选择\"Diagram→Property\"的功能项目,并且在\"Logical Diagram\"的对话框中选择\"Diagram\"的标签,把\"Use Alias if Available\"的复选框选起来,并按下【确定】按钮,就会看到原先所设置的\"alias\"呈现在图中。 图3-6 在Diagram Property对话框选择\"使用别名\"的选项 (点击查看大图)图3-7 让类图呈现中文说明 Step 3:新增\"医生\"类,并建立其与住院事件中的\"关联\"。

请利用EA的\"Quick Link\",快速建立一个\"医生\"类,并同时建立其与住院事件的关联。

(点击查看大图)图3-8 利用\"Quick Link\"同时建立\"医生类\"与关联 请参考Step 2的做法,定义\"医生\"类的名称为\"Doctor\",别名为\"医生\"。

接着,请在\"Association\"上双击鼠标,并在\"Association Properties\"对话框中选择\"Target Role\"标签,在\"Doctor Role\"中键入\"doctorInCharge\",\"Alias\"中键入\"主治医生\",\"Access\"选择\"Private\",并且在\"Multiplicity\"中选择\"1\";接着选择\"Source Role\"标签,在\"Access\"选择\"Private\",\"Multiplicity\"选择\"0..*\"。

图3-9 设置\"医生\"类在该Association中所扮演的\"角色\" 图3-10 设置\"住院事件\"类在Association 中的\"多重性\"及\"访问权限\" 完成后的类图如下图所示: (点击查看大图)图3-11 建立住院事件与医生的\"关联\"关系后的类图 接着,请再次利用\"Quick Link\"连接\"住院事件\"与\"医生\",并在该关联中设置\"医生\"的角色为\"resident\"、\"住院医生\"、\"Private\"及\"1..*\";而\"住院事件\"的角色为\"Private\"及\"0..*\"。

Step 4:新增类,并建立其与\"住院事件\"的关联。

参考Step 3及图3-12,分别新增\"SickBed\"(别名为病床)、\"Nurse\"(护士)、\"Symptom\"(病征)及\"MedicalTreatment\"(医疗处置)4个类,并建立其与\"住院事件\"的关联。

Step 5:建立基本属性(Attribute)。

完成Step 4后,请依据图3-12的设计图,在\"住院事件\"的类加入一个属性(Attribute),命名为\"hospitalInDate\",别名为\"住院日期\",数据类型为\"DateTime\",访问权限为\"Private\"。

(点击查看大图)图3-12 建立\"住院事件\"的基本属性 接着,请分别在\"病床\"类中加入两个属性:

名称:nHIExpense、别名:医保补助费用、数据类型:int; 名称:department、别名:科别、数据类型:String。 最后,在\"医疗处置\"类加入一个属性:

名称:treatmentDate、别名:处置日期、数据类型:DateTime。 Step 6:修改\"病床\"类的类型,并加入\"操作\"(Operation)。

请参考图3-2,可以看到在设计图中,\"病床\"这个类的类名称是斜体的;在UML中将该类称为一个\"抽象类\"(Abstract Class),因此,必须先修改\"病床\"这个类,请在工作区中双击鼠标,弹出\"Class\"对话框,并把\"Abstract\"的复选框勾选起来。

接着,请在\"病床\"类按鼠标右键,选择\"Operations?\"功能项目,弹出\"Operations\"对话框,并新增一个Operation:

名称:calculateExpense、别名:计算费用、参数:空、返回值:int、Abstract:选取。

图3-13 将\"病床\"类设为抽象类 图3-14 建立\"计算费用\"的操作(Operation) Step 7:建立\"病床\"的特化类。

最后,由于病床的费用计算方式不同,我们分别建立了病床这个类的两个特化类。 同样利用\"Quick Link\"选择新增一个特化的类,命名为\"NHISickBed\",别名为\"医保病床\"。

(点击查看大图)图3-15 建立一个\"医保病床\"类 当按下【确定】按钮时,会出现一个\"Overrides & Implementations\"的对话框,请选取\"SickBed::calculateExpense\"的操作。 (点击查看大图)图3-16 指定实现的操作 同样的操作,另外新增一个命名为\"OESickBed\",别名为\"自费病床\"的病床类的特化类。 完成后的类图如下图所示:

(点击查看大图)图3-17 信仁医院住出院系统领域模型

6. 系统结构与序列图

3.2.1 信仁医院案例背景描述

当HSDc的软件架构师与信仁医院的特助访谈过后,HSDc的内部召开了第一次软件开发会议,参与会议的成员有HSDc的RA、HSDc的软件架构师及该项目的设计人员。以下是该会议进行的场景。

HSDc RA:根据前两次与顾客的访谈,我找出了有关目前开发项目的相关用例模型,请看:

图3-18 HSDc RA展示的用例模型 项目设计人员:在这个用例模型中,我们应该优先做哪一个用例?

HSDc RA:应该从\"通知住院\"开始做起吧!毕竟这是第一个会用到的用例,而且我们要尽快开出接口规格(API)给门诊系统的开发商进行测试。

HSDc软件架构师:特助确认过了吗? HSDc RA:特助也是这样想的。

HSDc 软件架构师:所以这个\"通知住院\"的用例是整个住出院系统中\"最有价值\"(Valuable)的用例喽!

HSDc RA:嗯?好像不是。如果谈价值的话,应该是\"登记出院记录\"会比较有价值。

HSDc 软件架构师:如果是这样的话,或许我们先实战\"登记出院记录\"会比较有意义;而且从绘制的用例模型来看,登记出院记录会接触到\"收费管理系统\",从我们的角度来看,这个用例由于接触到外部系统,它的风险也会比较高。

HSDc RA:这样吗?但是没有通知住院,也没有登记住院记录,怎么实战\"登记出院记录\"呢?

HSDc 软件架构师:这倒不是问题,用例都是各自的,在开发上,并不需要考虑到流程的先后次序。

HSDc RA:哦。

项目设计人员:好的,那我们就从这个用例开始实战。那这个用例的叙述完成了吗? HSDc RA:已经完成了正常流(Normal Flow)的信息搜集了。 项目设计人员:这样啊!那是不是要搜集更多的信息再开始实战?

HSDc 软件架构师:不用了。我们这次项目采取\"迭代和增量\"(Iterative And Incremental; I&I)的开发方式,第一个迭代(Iteration)就只要实战正常流就可以了。

项目设计人员:了解了。那我们要从哪一张设计图开始实战?

HSDc 软件架构师:嗯,这是我跟信仁医院特助沟通过后的领域模型,请看:

(点击查看大图)图3-19 HSDc软件架构师展示的领域模型 我想我们可以根据这个领域模型来实战\"登记出院记录\"的用例。 项目设计人员:所以我们直接参考用例跟这张领域模型来开发喽!

HSDc 软件架构师:嗯。原则上,这张领域模型并没有经过验证。可否请你设计一张\"序列图\",然后使用Jacobson的\"分析类\"来实战\"登记出院记录\"的用例。

项目设计人员:了解了,那我就开始绘制\"序列图\"喽! 3.2.2 问题与分析

一般来说,我们在用例分析中,把系统应该要满足的用户期望找出来了;而在类图中,则是把系统的架构构造出来。但是,针对每一个特定之用例的场景(Scenario),要如何利用类图所规范的对象,来完成用例所交付的任务,就必须要利用序列图来表达。

序列图最主要的目的,就是在表达对象与对象之间如何沟通与合作,也因此,我们才会称序列图是一个动态的模型。

一般来说,序列图的主要任务包括:

表达设计者心中对于未来程序在运作时的对象协作模型。

由于目前大部分的实战平台都是由\"面向对象编程语言\"(Object-Oriented

Programming; OOP)所开发的,因此,设计者在实际开始写代码之前,必须要先在心中构造一个\"对象模型\",而序列图正是这个\"对象模型\"的其中一种展现方式(另一个展现方式则是通信图)。

验证软件领域模型的正确性。

序列图的基础还是从抽象层次的类图而来,因此,序列图中所有的元素,都必须在类图中存在着。正因为如此,有经验的设计人员会利用绘制序列图的机会,重新审视自己设计的领域模型的正确性。

提供程序员(Programmer)编码的蓝图。

序列图表达的方式是以时间为纵轴,这也恰巧符合编码的方式,一样具备\"次序性\"(order)。不过在绘制序列图时,要先打破:序列图并不需要\"务求精细\",因为它毕竟只是一个\"蓝图\",并非完整的\"施工计划\"。许多设计人员过于执着于序列图的细节,反而造成序列图过于复杂,这就丧失\"蓝图\"的目的了!

有关用例与序列图间的关系,我们将会在第2篇的实战案例中做更进一步的介绍。 3.2.3 序列图的基本认识

我们以一个申请请假的序列图为例说明。

图3-20 申请请假的序列图 同样,我们也针对上图中的几个要素加以说明。 对象(Object)

在序列图中,每一个参与的部分都是\"对象\"。

\"对象\"在UML的表达,主要以\"对象名称:类名称\"的方式来表达。若在对象的表达上,使用\":类名称\"来表达的话,那代表该对象并没有被指定特定的名称(Anonymous)。

消息(Message)

对象与对象之间,必须要通过消息来传递。所谓的消息,其实就是该对象所属类的某一个操作(Operation)。若该消息并未被定义在对象所属的类中,可以使用\"// 消息名称\"的方式来说明。

两个对象间若能够沟通消息的话,这代表着在类图中,该两对象所属的类必然有关系(Association、Whole-Part、Generalization或Dependency)。

生命线(Lifeline)

对象有其生命线,因此,在序列图中,对象必须要在其生命线中才能够彼此交换消息。序列图中,时间的因子主要利用由上而下的方式来呈现。

3.2.4 信仁医院住、出院系统的序列图范例

根据Jacobson的说法,序列图的主要目的在陈述用例的正常事件流(flow of events)中,对象彼此间的交互关系。

An interaction diagram shows in detail the interactions that take place between the objects during a use case's flow of events.(《The Object Advantage》, Jacobson, 1994, p. 132)。

也就是说,序列图的主要来源其实是用例的叙述。

有关用例叙述的写作原则,第2篇将会更进一步地介绍。因此,本范例将直接提供\"登记出院记录\"的用例叙述,来作为绘制序列图的基础。

登记出院记录的用例叙述(正常流) 1. 医护人员提供[患者出院申请记录]。 2. 系统保存[患者出院申请记录]。

3. 系统提供[患者住院信息]给收费管理系统。 4. 收费管理系统提供[住院费用]给系统。 5. 系统根据[病床费用计算逻辑]计算病床费用。 6. 系统保存[患者出院信息]。

根据这个用例叙述,\"登记出院记录\"的序列图应如下图所示:

图3-21 \"登记出院记录\"的序列图 3.2.5 在EA中绘制序列图 Step 1:选择放置序列图的位置。

放置序列图的位置跟一般的图形不大一样,并不是放置在特定的\"包\"(Package)中。通常,序列图是表达对象如何合作,进而来完成某一个用例的任务的,因此,序列图似乎要放在用例当中才合理。

不过因为UP(Unified Process)对于序列图放置的位置有特定的地方,因此,我们将会参考UP的做法。

首先,请在ch03-2-example.EAP中的\"Model → Domain Model→信仁医院住出院系统\"下新增一个Package\"Use Case Realization\";在\"Use Case Realization\"下新增一个Element - Collaboration,命名为\"登记出院记录Realization\";接着,在\"登记出院记录Realization\"下新建一张\"Sequence Diagram\"。

图3-22 新增一张Sequence Diagram Step 2:将\"登记出院记录\"用例的主执行者\"医护人员\"拖曳至工作区,并选择\"as Instance of Element(Object)\"(在图中新增一个医护人员的对象)。 图3-23 新增\"医护人员\"到序列图中,并指定为一个对象 Step 3:将\"RecordHospitalOutBpo\"类拖曳至序列图中,并选择\"as Instance Of Element\"。 图3-24 在序列图中加入\"RecordHospitalOutBpo\" 在\":医护人员\"对象选择\"Quick Link\"连线到\":RecordHospital OutBpo\"对象。 图3-25 利用\"Quick Link\"建立\":医护人员\"与\":RecordHospitalOutBpo\"的Message 单击两个对象的Message,并在\"Message Properties\"对话框中选择\"Operations\"按钮,以建立\"RecordHospitalOutBpo\"的操作。 图3-26 建立Message时,同时建立Bpo的Operation 在\"Operation\"对话框中,建立一个新的Operation,命名为\"applyHospitalOut\"、参数为\"hospitalOut: XML\"、别名为\"申请患者出院\"。 图3-27 新增一个\"申请患者出院\"的Operation Setp 4:重复Step 3直到完成所有的序列图。

7. 系统结构与通信图

信仁医院案例背景描述

HSDc的软件架构师拿到了项目设计人员所绘制的序列图(图3-21),但无法确定是否符合领域模型(图3-19),因此,他与项目设计人员进行了第二次的会议。

HSDc软件架构师:我看到了你绘制的序列图,可是觉得似乎有些问题,是否可以解释一下这张序列图跟领域模型的关系。

项目设计人员:没有问题。依照上次会议的结论,我采用Jacobson的BCE

(Boundary-Control-Entity)的分析类来进行设计。因此,我先针对\"登记出院记录\"的用例,建立了一个\"控制对象\"(Control Object),并命名为\"登记出院记录BPO\"。

HSDc 软件架构师:这个我了解。我先拿你的设计图来说明。

接着,HSDc 软件架构师将序列图与领域模型放在一起做比较,并且把有疑虑的部分画出来跟项目设计人员讨论。

HSDc软件架构师:如同我所标示出来的,在领域模型中,\"登记出院记录BPO\"并没有和\"病床\"类有任何的关系,该关系是通过\"住院事件\"来连接的,但是在序列图中,\":登记住院记录BPO\"的对象却和\":病床\"对象有消息传递,这似乎不大符合领域模型的设计。

项目设计人员:我看看。嗯,好像真是这样耶!

HSDc软件架构师:你可否画出另外一张对象协作图(Interaction Diagram),并且同时表达对象结构与消息调用,来确认你的设计并没有违反领域模型。

项目设计人员:我可以在序列图当中用说明来代替吗?因为我觉得序列图对于程序员来说,似乎比较直觉。

HSDc 软件架构师:我并没有说要取消序列图啊!序列图仍然是给程序员进行程序设计的蓝图,我要的是一张可以直觉了解的对象模型。

项目设计人员:了解了,那我另外画一张\"通信图\"(Communication Diagram)来表达。 HSDc 软件架构师:太好了。

图3-28 HSDc软件架构师对于领域模型与序列图间的不一致所提出的意见 3.3.2 问题与分析

在前述的场景中,其实已经说明了\"通信图\"的适用时机。

根据Jacobson原始的想法,\"通信图\"与\"序列图\"其实都在表达同一件事情:对象相互合作,以达成用例的\"事件流\"(flow of events)。说穿了,这两张图其实是同一件事的两面,而许多的UML工具(如IBM的RSA或Borland的Together)都支持这两张图的互转,这也代表了这两张图的密切关系。

若从架构师的角度来看,他所关心的是领域模型是否可以被完整转成对象模型,因此,会比较喜欢看到通信图。而从程序员的角度来看,序列图则比较能够表达程序的逻辑,因此,通常会要求设计师使用序列图来表达。

不过就目前比较主流的开发程序来看,使用\"序列图\"来表达对象结构,似乎变成\"唯一\"的方式。事实上,针对不同的问题,选用不同的图形,才是使用UML来沟通的\"王道\"。

以前述的场景来看,HSDc软件架构师所关心的问题是:究竟项目设计人员在设计序列图时,心中是否存在着对象的模型,也因此,他希望项目设计人员能够利用\"通信图\"来重新审视自己对于对象模型的理解。但是,针对未来给程序员的编码来说,HSDc 软件架构师仍然偏好使用\"序列图\"代替\"通信图\"。

也就是说,\"通信图\"可以视为架构师\"凝聚对领域模型理解\"的一个重要工具,而非\"必要产出\"。软件设计人员在决定使用何种UML图形来帮助沟通时,务必要先理解这个图形的特性,以免误用。

在笔者多年的软件顾问经验中,有许多的\"面向对象狂热支持者\",非常不喜欢使用序列图来表达对象协作,而偏好用\"通信图\"来表达,在他们的主要观点中,\"序列图\"其实看起来似乎比较偏向传统的结构化程序设计的图形,而不像通信图有\"对象结构\"在其中。这其实是对于\"交互图\"(Interaction)的一种误解。

在前面讲述\"序列图\"时,笔者曾经引用Jacobson对于交互图的定义,其中一个非常重要的关键在于:交互图的目的在于陈述\"用例的事件流,如何被对象模型所满足\"。也就是说,交互图的关键在于\"事件流的清晰度\",而非\"对象模型\";也因此,若是谈到\"交互图\"的基本特性,其实\"序列图\"比\"通信图\"更直观。

在第2篇的软件实务演练中,我们将更进一步探讨用例的事件流与交互图相互的关系,有兴趣的读者可以反复验证这一段说法,相信会有更深一层的体会! 通信图

3.3.3 通信图的基本认识

同样,我们先用一张表达车子、引擎与轮胎关系的通信图,作为解释通信图语法的范例。

图3-29 表达人、车交互与车子内部处理的通信图 在通信图中的几个重要元素,介绍如下:

对象(Object)

和序列图一样,通信图中所有的元素都必须是\"对象\",对象表示法,同样是利用\"对象名称:类名称\"来表达。

链接(Link)

对象与对象之间的关系,主要是\"链接\"关系,这代表着某个对象\"认识\"另一个对象。链接关系的UML图形是

链接关系也可以有方向性,称为\"Directed Link\",可以用一个箭头代表这个方向性,如图3-29所示中的司机与车子间的链接关系即为一个有方向性的链接,这代表着\":司机\"对象认识\":车子\"对象,但\":车子\"对象不认识\":司机\"对象。

消息(Message)

消息的表达语法与序列图相同,但在消息中,必须要特别表达消息的传递是由哪一个对象到另外一个对象。消息的标准表达图示为

3.3.4 信仁医院住、出院系统的通信图范例

在经由前面场景的讨论后,HSDc项目设计人员依据HSDc 软件架构师的要求,设计了一张\"登记住院记录\"的通信图,该通信图的实际产出,如下图所示:

图3-30 \"登记住院记录\"的通信图 请比对一下图3-19的领域模型与这张通信图,看看通信图是否符合领域模型的设计。

3.3.5 在EA中绘制通信图

请利用在\"3-2-5 在EA中绘制序列图\"的产出,继续在EA中绘制通信图。 Step 1:选择放置通信图的位置。

图3-31 新增一张Communication Diagram 一般来说,通信图都放置在跟序列图相同的位置。以这个例子来说,我们会放置通信图在\"登记出院记录Realization\"的Collaboration下;请在该Collaboration下新增一张\"Communication Diagram\"。

Step 2:将\"登记出院记录\"用例的主执行者\"医护人员\"及\"登记出院记录BPO\"拖曳至工作区,并选择\"as Instance of Element(Object)\"(在图中新增一个医护人员与登记出院记录BPO的对象)。

接着,请利用\"Quick Link\"在\":医护人员\"与\":登记出院记录BPO\"间建立一个链接(Link)。

图3-32 建立\"医护人员\"与\"登记出院记录BPO\"间的Link关系 Step 3:单击Link,并且利用鼠标右键选择\"Add message from :医护人员to :Record- HospitalOutBpo\"的选项。 图3-33 加入一个Message到Link中 双击Message,在\"Message Properties\"对话框中的\"Message\"字段,选择\"applyHospitalOut(XML)\"操作。 图3-34 \"Message Properties\"对话框 Step 4:重复Step 3直到完成图3-30的通信图。 8. 总结

在UML中,系统的内部结构分为静态结构与动态结构,静态结构是利用\"类图\"来表示,动态结构则是使用\"序列图\"或\"通信图\"来表达的。

类图主要表达的是问题领域的\"抽象概念\",在这个抽象概念中,除了表达该抽象概念的名称外,另外需要表达该抽象概念的\"属性\"与\"行为\"。

类图的目的是在进行软件开发前,先对软件所需面对问题领域的本质做一个通盘性的了解,但是类图在刚开始设计的阶段,并不会完全正确,必须通过后续的检验才能够逐渐接近真实的领域模型。

类图的产生并不是由软件设计人员凭空想象出来的,必须要参照领域专家对于领域的了解及对象的本质性概念来构筑而成。

序列图及通信图的目的都在于说明对象的协作如何达成系统的目标。系统的目标在进行用例分析时,已被区分为多个子目标,因此,每一张序列图所表达的,都是每一个用例是如何通过对象交互来完成的。然而,由于系统的概念模型已被定义于领域模型中,因此,对象模型的基本来源仍是\"类图\",所有对象间的协作关系,必须符合类图中的定义。

对于软件开发过程而言,序列图的表达方式比通信图更适合作为标准的产出。由于序列图是以时间为横轴,因此对于未来的程序设计而言,序列图具有\"蓝图\"的效果,但若是需要同时表达对象的结构与彼此间的协作关系时,则需要使用通信图才能够有比较完整的呈现。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- aiwanbo.com 版权所有 赣ICP备2024042808号-3

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务