UML软件工程组织

 

 

UML在概念模型中的运用分析
 
2008-04-03 作者:何云 来源:soft6.com
 

摘要:UML的目标是以面向对象图的方式来描述任何类型的系统,其中最常用的是建立软件系统的模型。本文运用UML,对软件开发过程中的概念模型进行了分析,研究了开发模型的整个过程以及其间涉及到的相关知识,对软件开发建模具有较大的指导意义。

关键词:UML 建模技术 概念模型

一.UML简介

UML是一种面向对象的建模语言,而不是一种面向对象的建模方法,它只是给出一套用于建模的元素及表示符号并定义了它们的语义,而不涉及如何进行系统建模,它本身没有提供过程的概念,这意味着用户在使用UML进行建模时,可以选用任何适合的方法和过程。过程的选用与模型/软件开发过程的不同因素有关,诸如所开发软件的种类(如实时系统、信息系统和桌面产品)和开发的目的等。用户将根据不同的需要选用不同的过程。然而,使用UML建模仍然有着大致统一的过程框架。该框架包含了UML建模过程中的共同要素,同时又为用户选用与其所开发的工程相适合的建模技术提供了很大的自由度。

鉴于此,Rational公司在Objectory过程框架的基础上,提出了统一过程(Unified Process)的概念,力争使其象UML成为标准的建模语言那样,成为进行信息系统开发的标准过程。使用UML进行建模的过程应包含以下三个基本特性:Use Case驱动、以体系结构为中心、迭代式的增量开发。

1.Use Case驱动

在UML中,Use Case捕获系统的功能需求,驱动软件的整个开发过程,确保分析中罗列的所有功能均被实现。由于Use Case中包含了系统中的所用功能描述,因此将影响到所有的开发阶段。

2.以体系结构为中心

使用UML进行建模的过程应该以体系结构为中心。这意味着应该在开发的早期尽量建立一个良好的系统体系结构,然后建立原型和进行评估,并在开发过程中不断的细化。体系结构把系统划分为几个部分,描述各部分间的关系、相互作用、通信机制以及添加和修改某一部分的原则。定义一个良好的体系结构对于实现一个易于修改、易于理解和可重用的系统至关重要。

3.迭代式的增量开发

使用UML建立模型时,不应试图一次定义出模型的所有细节,而应分成一系列较小的迭代过程,在每个迭代过程中逐步增加信息,逐步进行细化。一次迭代或一系列迭代可认为是对系统进行功能完善的过程,即完成系统的一次增量。迭代和增量式开发就是定义一系列的开发阶段。

UML的目标是以面向对象图的方式来描述任何类型的系统,具有很宽的应用领域。其中最常用的是建立软件系统的模型,当然它同样可以用于描述非软件领域的系统,如机械系统、企业机构或业务过程,以及处理复杂数据的信息系统、具有实时要求的工业系统或工业过程等。总之,UML是一个通用的标准建模语言,可以对任何具有静态结构和动态行为的系统进行建模。

二.概念模型的UML描述规范

从表达能力来看,UML无疑是很强的,它从参加联合的各种面向对象方法中吸取了许多扩充的概念和图性。但恰恰因为这一点,UML的复杂性也远远超出了以往各种面向对象方法,以至它所使用的建模元素达到一百多个,开发一个系统要画的图达9种之多。UML没有指明它要求建立的9种图有哪些是可以缺省的,以及在什么情况下,对哪类系统可以缺省。实际上UML的各种图对建模问题的表达能力有很大的冗余性。例如,协作图中表达的静态信息(关联、关联端点、可导航性等)都可以在静态结构图中表达,而它对消息的表示也没有提供比顺序图更多的信息。建模元素的繁多是UML的另一特点。尽管在UML的设计中考虑到“必须在表达能力和简单性之间作出折衷”,但是从实际结果来看似乎还是倾向于复杂。

由于以上原因,在使用UML对使命空间概念模型进行描述时,应当避免随意性、遵从一定的描述规范,即用什么UML建模元素表示概念模型的描述要素,对UML表示有哪些限制、约定,遵从什么表示习惯等,这样才有利于模型开发人员之间的交流,并促进概念模型的重用性。

1.描述概念模型所需的UML建模元素

在UML的五大类图中,在描述概念模型时只有实现图是不需要的,因为我们所描述的毕竟是概念模型,与具体实现无关。其他四大类图中也并不是全部用到,一般只用到下面几种图:

1) Use Case图

Use Case图主要用于顶层的功能性描述。Use Case图中主要用到Use Case、作用者和联系这三类UML建模元素,除此之外,依据实际情况还要用到类图中的一些UML建模元素。

2) 类图

类图主要用于表示实体等这一类实在的现实对象及其相互关系,具体而言,类图中一般要用到这些UML建模元素:类、联系、聚合、泛化、联系类、接口、依赖等。

3) 状态图

状态图中一般要用到这些UML建模元素:状态、状态转移、子转移、起始状态、终止状态、判断、同步等。

4) 活动图

活动图实际上是状态图的超集,活动图中除了要用到状态图中所使用的建模元素外,还要用到这些UML建模元素:活动和泳道。

5) 顺序图

为了全面地说明各实体间的信息交互的流程,即每个实体的整个生命期内以及各实体间的交互时序关系。可以通过顺序图,用对象间的消息交互,表示实体间的信息交互的流程。顺序图中一般要用到这些UML建模元素:对象、对象消息。

2.UML描述风格

2.1 EATI的UML描述风格

EATI(实体、动作、任务、交互等)用UML建模元素表示时,可用版式(stereotype)加以标识。

a.Use Case的表示

Use Case的命名方式:以简洁的文字说明Use Case所代表的功能。对Use Case的附加说明则放在Use Case规范的文档中。作用者对于Use Case的作用可用联系名具体说明。

b.实体和关系的表示

实体是可以用UML的类来表示的,实体的相关内容可以放在类的属性里表示;与此相应,实体间的关系则是用类间的联系来表示的,可以使用版式或命名来区分不同的关系。现实世界中实体间的组合关系可以方便的用UML中类之间的聚合(Aggregation)联系来表示。

c.动作、任务和交互的表示

任务是由UML的活动图中的活动元素来表示的,动作是由活动图中的动作来表示的。而任务间的交互则是用活动间的状态转移来表示的,交互中所传递的消息、事件等则放入转移规范中的事件里。

在活动图中任务间的时序关系是这样表示的:①若两个任务间有表示状态转移(state transition)的线,则表明该两任务是顺序关系。②放在两个同步符号中间的任务表示并发。③嵌套任务同样用放在两个同步符号间的任务表示,只不过在生命期短的任务的前后各加上一个空任务,从而表示生命周期的嵌套。如图1所示,表示任务A嵌套任务B。④嵌套任务同样用放在两个同步符号间的任务表示,只不过在开始时间晚的任务的前加上一个空任务,而在结束时间早的任务的后面加上一个空任务。⑤任务的重复是用自身转移表示的。如图1所示,表示任务A的重复执行。

图1 任务时序关系图

状态转移上的文字一般是指当某事件发生时,从一个任务转移到另一个任务,这也包含了一种时序关系。这些事件同样指出了任务的进入和退出的条件。至于任务中的条件及条件从句,在活动图中归结为事件和对事件的反应。

任务中的其他描述成分,如初始状态、输入(实体)、动作限制、输出(实体)、最终状态、任务描述等,均放在活动图的文档(document)中。对输入的响应,如对事件的响应;而发送输出实体相当于发送事件。在活动图中任务间的执行者(即动作的主语)是这样表示的:以泳道(swimlane)来表示执行动作的实体,放在某个泳道中的任务或步骤表示其动作的主语是该泳道表示的实体。

在活动图中一般都有起始状态和终止状态,在表示任务时,用这两个状态来充当类似“模块接口”的作用。具体来说,就是对某个具有若干输入和输出的任务进行分解时,分解后的活动图中的从初始状态引出的状态转移与上一级的输入相同,而引向终止状态的状态转移与上一级的输出相同。这样做的原因是模型的一致性所要求的。

d.顺序图的表示

顺序图的表示遵从一般的UML语法即可,只是对于对象消息的命名应当符合表达习惯。

2.2 体系结构产品的UML描述风格

并不是所有的体系结构产品都适宜于用UML进行描述,有些产品用表格式的方法来表示这些产品更直观和易于理解,尽管这些产品中的大多数实际上仍可以从相应的UML图中推导出。

三.开发概念模型的指南

两条主要的指南形成了开发概念模型的面向对象过程的基础。第一条是“自顶向下、广度优先”,第二条主要依赖于基于事件的交互作为描述和分析的技术。下面,我们对这两条指南进行一下阐述:

1.自顶向下、广度优先

第一条指南是体系结构的规范说明过程应当遵循自顶向下、广度优先方案。“自顶向下”意味着该过程开始时将软件系统看作一个黑箱,与外部的(范围外的)实体相连或相关。在最初的上下文中,系统被分解成一些主要的部件,然后那些部件被近一步分解,如此下去。分解过程通过每个附加的层次从几何上扩展,最终对任何项目可以实际处理的分解深度施加实际限制。“广度优先”意味着随着深度增加分解应当在整个体系结构范围内被统一执行——不应当在体系结构的某一特定范围进行特别深入的分解而造成“烟囱”似的结构。这条指南的理论基础在于统一的自顶向下、广度优先是保证正确的体系结构实现和系统需求、减少修复前期烟囱式设计所必不可少的返工、避免体系结构的一部分“驱动”其它部分不必要的需求、接口和行为所必需的。

2.基于事件的交互

第二条指南是我们强烈的依赖于对象间基于事件的交互作为定义机制。无论对象代表一个复杂系统或一个软件,其输入输出事件都是说明对象行为的关键信息。这些行为可通过形式化的状态图来捕捉,在此应当注意到系统仅对其输出有控制权,而其输入由系统环境决定不受系统的控制(即在视野范围内的系统外部)。

四.开发概念模型的面向对象过程

图2表示了整个开发概念模型的面向对象过程主要的迭代特性。迭代循环主要的输入和输出是系统的行为,其中“预期的”(as desired)行为作为输入、“建模的”(as modeled)行为作为输出。这两种情形下,系统行为都通过使用UML顺序图来表达。应注意其它一些技术和方法学是以别的名字称呼这一基本图形的,如事件跟踪图、消息顺序表等。迭代循环的要素如下:
①以顺序图的形式定义一些行为,这些就是“预期的”行为,这里涉及的是对象实例,而不是类;
②构造新的对象类(从前一步中的对象实例导出)及其相关的状态图,或修改现存的一些;
③为所有的Use Case产生行为(还是以顺序图的形式),这些就是“建模的”行为;
④比较“预期的”和“建模的”行为,如果两者匹配,则继续为新的行为建立模型或继续为对象分解的下一级建立模型,如果匹配不充分,对象类及其状态图则需要进行再工程,通常会出现下列两种情况之一:“建模的”行为规定得不够或需要重新设计。

图2 整体开发过程的迭代特性

下面,我们对完整的开发概念模型的面向对象过程按照实施的步骤进行说明:

1.对于最初的Use Case,第一步是将Use Case图翻译成高层的顺序图,它主要涉及在外部作用者和系统(视为单一实体)之间信息交换的顺序。初始的对象类图和状态图可以从此导出,这将产生“建模的”行为(嵌入在顺序图中)。这些最初的图代表第一次迭带。接下来的迭代从在顺序图和对象图中分解一个或多个对象开始,定义顺序图中更精确(详细)的行为并通过修改或附加的状态图来实现哪些行为。这样的迭代将进行下去,阐述额外层次的细节,直到Use Case的需求得到满足。当阐述后续的Use Case时,或许有必要将行为定义到附加的层次细节。必须认识到导出的类和状态图代表通过所有的Use Case和顺序图捕捉到的行为的结合。将附加的行为集成到现有状态图集合中的过程有时候会是一个挑战,还会是理解一个多任务系统需要如何装配的关键。

许多开发人员曾批评过UML的Use Case图根本不像面向对象风格的(除了外部作用者外,它看上去更像面向功能的而非面向对象的)。但是它的价值在于为后继的分析正确设定上下文并提供外部消息接口的方便视图。我们建议用基本的系统功能来标识此Use Case。(其他主要的系统使用或功能应当表示成单独的Use Case。)作用者和Use Case之间的单向箭头代表作用者和系统之间的基本交互。初始、顶层的Use Case阐述了外部作用者和作为一个单一实体“系统”间的关系。Use Case图的重要价值之一就是对图形附之以文字描述。

2.在给出了一个或多个Use Case后,下一步就是将这些Use Case转化为高层的顺序图。顺序图是UML中两种交互图之一(另一种是合作图)。这两种交互图可以互换,而没有信息损失。因此选用哪一个主要是风格问题而不是技术问题。

顺序图表示实体间事件或消息交换的事件顺序,在这个特定的步骤中,实体集合应当限定为对应于Use Case的外部作用者和一个代表整个“系统”的实体。第一个顺序图应当只含一个“系统”实例外加必需的外部作用者,以便集中注意力于系统与外部世界的顶层界面。通过按时间排序实体间的交互可以将顶层的Use Case图直接转换成顺序图。应当为每一个Use Case构造一个顶层顺序图,并且在这个图中用单独的实体表示整个系统。

3.接下来是从刚刚创建的顺序图中提取初始的系统视图的信息对象。顺序图中的事件代表可用于直接创建初始的(信息)对象类的事件和信息。这些将会放在对象类等级图中。在顺序图中若将事件视为刺激—响应对偶,那么通过在每个刺激和对应的响应之间加入联系就可以构造最初的联系集。应当注意,在很多情况下,对于第一个刺激的响应或许会成为第二个刺激,导致遵循对象类图的因果链(尽管在对象类图中,联系是无方向的)。随着其它顺序图被开发出来,类图将作相应修订和扩展。当类图完成、不需进一步改动时,就是完整的逻辑数据模型。

4.再次要对现已存在的顺序图进行处理,这是功能分解的推导源头。代表最初的Use Case的椭圆是以功能-类型名(动词/动作短语)来标识的。现在让我们回到顺序图看一下系统生命线。从系统收到第一个事件到产生第一个输出事件之间,系统必定执行了某种动作或功能。我们建议在系统生命线的输入和输出事件之间加入功能名。通过观察对象、刺激和响应,设想完成所希望的基于输入的输出的功能是相当直接的。通过沿着系统对象的生命线加入功能(注意,沿作用者的生命线定义功能并不重要,因为他们处于系统外部,不在关心范围之内),可以粗略的定义一起完成较高层功能(即Use Case的名字)的多个子任务,顶层功能已借助基于顺序图的技术分解过了。既然在顶层Use Case图中的活动(椭圆)以功能名来标识,从而用来扩充顺序图的功能实际上是Use Case活动的子功能。

从系统对象顺序图中构造的功能层次图可以推导出UML活动图。功能层次图在每一次对象分解迭代中会增加额外的叶结点,因此只有对象分解过程中止时它才能称得上“完整”。需要着重指出的一点是功能层次图是从顺序图中导出的,而不是单单检查系统本身。

5.将已分解出来的“系统”的部件对象代替顶层顺序图中的系统对象。原来已存在的作用者与系统之间传递的事件,现在这些事件将从作用者传递到某个或某些个系统的部件对象。在这些部件对象之间也要添加新的事件(这些事件在顶层的顺序图中是不可见的,因为他们完全是内部事件)。当修改现存的事件并加入新事件时,又会观察到因果关系。在新对象生命线上再加上功能名,从而得到一个新的扩充顺序图。通过比较新旧扩充顺序图,可以看出上一层的功能已被下一层中的功能分解所代替。在此,当对象分解过程如果已经达到了足够详细的程度,就可以开始为对象类构造状态图了。否则,还需要进一步分解。

6.对于所有在一个或多个顺序图有实例的系统对象类,都需要开发其状态图。对于一个给定的类开发其状态图的过程开始于扩充状态图。从顺序图中将该类的对象生命线和与之相连的输入输出事件抽取出来,这是开发该类的状态图的起点。抽取出来的生命线有许多输入和输出事件与之相连,将这一系列事件转换成状态图的一般规则如下:

输入事件是与导出某个状态的转移相关的,输入事件应当是导致转移点火的触发事件。因此在生命线上可通过在触发事件之前加入对象的状态来进一步标识。这种技术UML并不支持,但在其他一些方法和工具中已被实现。

输出事件是由对象采取的某些动作产生的(即方法、操作、函数等)。如状态图规则所约定那样,动作可以与一个转移、或状态的进入和退出相联系(经由某个转移)。入口和出口代码,就像他们的名字所显示的那样,在某些复杂行为情况下很有用,但在本文中并未阐述这一点。不失一般性,这里的讨论仅限于一有限子集:动作假定仅与转移相关。即使在软件开发中,在这种限制下,也能够实现系统而只是会产生一些冗余代码。

7.应当检查生命线的循环模式。并不是所有的对象都有循环模式。通常一些数据类型对象(信息对象)生存期是短暂的,其活动状态图不是循环的。另一方面,许多对象预期执行多次同一任务,他们的状态图将是循环式的。可以构造系统对象图的另一版本以达到使用UML联系构造来指示物理接口的意图。这里用到的另一个有用的UML构造是“连接属性”(称为“联系类”),这种构造用于表明系统对象之间的联系是实际的(接口)类。

8.在给出类结构以及完整的顺序图后,就得到了将事件和消息与系统接口相关联的全部信息。通过在表示物理接口的联系类中加入由该物理接口传输的消息、事件等的文字说明,就得到了消息-接口映射图或消息-接口图。为了支持包含通信带宽需求或用户界面/人为因素等问题的系统分析,这种相关性是至关重要的。

五. 一个可行技术的探讨

构造体系结构的主要动机之一是处理演化系统自有的问题。在这里,我们将阐述使用UML图来处理划分时间阶段系统的一个可行技术。本技术基于对类图的使用和子类(特化/泛化)的正确构造,还依赖于对象类是否是可实例化的。在定义上,高层类(父类或超类)比其子类更具抽象性,定义了其子类的共同特征。这样的话,我们不能实例化高层的抽象类。应注意在有些情况下父类是可实例化的。这些类,不管父类还是子类,都可以进行实例化。另一方面,对于“人”这样的类(有子类“女人”和“男人”)是不能实例化的——只有它的子类可以有自己的实例,因为任何人必须要么是男人要么是女人(子类是互斥的并构成了完整的“人”集)。

使用可实例化子类的策略是标识/创建一个子类集合(或在不同父类下的几个可能的集合)使得对应于系统的每一阶段都有一个子类集。我们可以创建类族,对于每一个系统阶段每一个类族都有一个单独的父类和子类。当以下的条件一个或多个满足时,决定了一个对象类需要重新改进为特定阶段子类:
①接口被从对象(类)中加入/删除;
②消息被从对象(类)接口中加入/删除;
③对象对给定刺激的反应发生变化;
④对象类属性的取值范围发生变化。

六.过程概述

在进行实际的想定描述之前,先要进行需求分析,目的是在用户和系统开发者间达成共识。概念模型的用户主要是软件开发人员和建模仿真人员,为此在这一阶段作为概念模型的开发者应当通过与用户的交流,清楚的了解用户期望的概念模型是什么样子的,表述习惯是怎样的,应当详细到何种程度。例如对如建模仿真人员来说,他们更注重任务等对于事件的响应,而软件开发人员在制定作业想定时,往往采用时间序列,因此在建立概念模型时应当弱化时间序列、强化事件序列。又如软件开发人员对使命空间的描述往往具有概括性、确定性的特点,即对软件细节、开发的变化情况缺乏详细的阐述;而仿真建模人员要建立起仿真模型的话,必须得到非常详细信息,包括许多软件开发人员认为理所当然的叙述,为了进行仿真建模必须提供更低级的细节。所以概念模型应当尽可能的从软件领域将这些细节“挖掘”出来,建立起现实世界到仿真建模领域的一座桥梁。这实际上是一个知识获取的过程。

1.定义和分析Use Case

在充分了解特定使命空间并和领域知识专家充分交流的基础上,使用Use Case技术进行想定的功能定义,附带定义Use Case的Use Case实例、性能度量等。这一阶段不一定要将所有的Use Case都列出来,只要列出比较重要的即可,其它的留待以后完善。

Use Case最初起源于软件工程领域,在软件开发中的Use Case图中,明显的分为两部分:作用者和Use Case。相对于作用者(大多数情况下系统的用户)而言,Use Case近似于“黑箱”,作用者只关心Use Case的外在表现,也就是它可以提供什么功能。然而在建立软件领域的使命空间概念模型时,模型的用户主要是软件开发人员和仿真建模人员,尤其是仿真建模人员它们更关心模型的内部细节,这时Use Case近似于“白箱”。既然是“白箱”,软件开发人员和仿真建模人员都可以深入其中,获取自己想要的信息。所以“白箱”里边的描述应当符合一定的软件规则、习惯、术语等,同时也应当遵从UML的语义,不至于给仿真开发人员造成误解。

在建立使命空间的概念模型时,Use Case模型的获取同软件开发过程中Use Case模型的获取有很大不同。在软件开发过程中,开发人员所建立的Use Case图、静态图、行为图和交互图等,并不提交给软件系统的用户,而这些图模型的用户恰恰是开发人员自己。开发人员最后提交给用户的是最终的软件系统。然而在使命空间中,概念模型的用户是软件开发人员和仿真人员,概念模型的开发人员提交给用户的却正是这些图模型(概念模型)。软件开发人员和仿真人员虽对概念模型表示的习惯、风格等有影响,但对于概念模型的内容并无直接作用,即他们影响概念模型的“形式”甚于“内容”。概念模型中的Use Case的作用者不再是系统外的用户等,而是系统内对它实施作用者。因此,在建立使命空间的概念模型时,Use Case模型的获取不同于软件开发过程中Use Case模型的获取。

我们知道,Use Case是对一个实体(响应实体)由于另一个实体的激励(激励实体)导致的行为的描述。基于此,我们认为在使命空间中,获取Use Case模型应当按如下步骤:

第一步,找出使命空间的激励实体和响应实体;

第二步,根据激励实体和响应实体找出对应的Use Case。

以上两步,往往不是一次性的完成,而是随着工作的深入,不断执行上述两步,完善系统的Use Case模型。

有时候需要对Use Case进行分解,将较高一级Use Case分解为低一级的Use Case,可以遵循如下原则:
①将某个Use Case的响应实体作为激励实体,找出该激励实体的下一级响应实体,进而导出下一级Use Case。
②如果某个Use Case所描述的功能可以分成相对独立的几块,则可据此分解Use Case。
但Use Case毕竟是用来表示高层的软件开发活动,故不应分得过细,应当适可而止。至于分解到何种程度合适,应当具体问题具体分析,不宜给出统一标准。

除了Use Case外,Use Case实例及其性能度量、条件、实体等都是用UML中的类图来表示的,他们的相关内容可以放在类图里的属性来表示。现实世界中实体间的组合关系可以方便的用UML中类之间的聚合(Aggregation)联系来表示。

2.任务分解与交互

一个任务可以分解为子任务或任务步骤。任务步骤是任务的原子成分。它不能进一步得分结尾子任务或任务步骤。一个任务步骤必须和对应任务必须共享同一Use Case。

进行任务分解应遵循某种原则。既然动作是任务表示的模板,任务的分解可以归结为动作的分解。动作的分解就是对谓语动词(Verb)、主语(Subject)和直接宾语(Direct object)的分解。所谓步骤,可以认为它是由“最小”的主语、谓语动词和直接宾语组成的。既然步骤是“最小”的,当然是不可分解的。对任务进行分解,一直分解到步骤而止。

任务间不是互不相关的,而是相互影响和相互制约的。使命空间的本质就是为了达成某种目的的若干任务的互相影响的执行,所以只有将任务间的交互描述清楚,才可以完整的建立其概念模型。

3.实体与关系

在第二步任务分解和交互的基础上,会得到许多实体,主要视任务的执行者、交互事件消息等。这一节主要是找出使命空间中的相关实体,并定义实体的能力、技术指标等,以及实体间的静态联系(包括关系联系、聚合联系、依赖联系等)。列出的所有实体都不是一成不变的,在整个开发过程中,由于经验的不断积累,可能会增删一些类的属性和操作,或者增加一些新实体,删除一些不再使用的实体。

4.顺序图的描述

为了全面地说明各实体间的信息交互的流程,即每个实体的整个生命期内以及各实体间的交互时序关系。可以通过顺序图,用对象间的消息交互,表示实体间的信息交互的流程。在描述完任务间的交互之后,顺序图可以自然推导而出,它可以给出使命空间信息流的全局概貌。

5.过程总结

该过程是以EATI为基础的,我们所做的只不过是用UML语言将EATI表现出来而已。EATI是表示的内容,本身没有过程的概念,而UML则是表示的形式。

 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号