三种关系详解
共性:都是从现有的用例中抽取出公共的那部分信息,作为一个单独的用例,然后通后过不同的方法来重用这个公共的用例,以减少模型维护的工作量。
1、包含(include)
包含关系:使用包含(Inclusion)用例来封装一组跨越多个用例的相似动作(行为片断),以便多个基(Base)用例复用。基用例控制与包含用例的关系,以及被包含用例的事件流是否会插入到基用例的事件流中。基用例可以依赖包含用例执行的结果,但是双方都不能访问对方的属性。
包含关系对典型的应用就是复用,也就是定义中说的情景。但是有时当某用例的事件流过于复杂时,为了简化用例的描述,我们也可以把某一段事件流抽象成为一个被包含的用例;相反,用例划分太细时,也可以抽象出一个基用例,来包含这些细颗粒的用例。这种情况类似于在过程设计语言中,将程序的某一段算法封装成一个子过程,然后再从主程序中调用这一子过程。
例如:业务中,总是存在着维护某某信息的功能,如果将它作为一个用例,那新建、编辑以及修改都要在用例详述中描述,过于复杂;如果分成新建用例、编辑用例和删除用例,则划分太细。这时包含关系可以用来理清关系。
2、扩展(extend)
扩展关系:将基用例中一段相对独立并且可选的动作,用扩展(Extension)用例加以封装,再让它从基用例中声明的扩展点(Extension Point)上进行扩展,从而使基用例行为更简练和目标更集中。扩展用例为基用例添加新的行为。扩展用例可以访问基用例的属性,因此它能根据基用例中扩展点的当前状态来判断是否执行自己。但是扩展用例对基用例不可见。
对于一个扩展用例,可以在基用例上有几个扩展点。
例如,系统中允许用户对查询的结果进行导出、打印。对于查询而言,能不能导出、打印查询都是一样的,导出、打印是不可见的。导入、打印和查询相对独立,而且为查询添加了新行为。因此可以采用扩展关系来描述:
4、泛化(generalization) 精化refine、实现realize
在用例的角度,泛化==实现 包含==精化
泛化关系:子用例和父用例相似,但表现出更特别的行为;子用例将继承父用例的所有结构、行为和关系。子用例可以使用父用例的一段行为,也可以重载它。父用例通常是抽象的。在实际应用中很少使用泛化关系,子用例中的特殊行为都可以作为父用例中的备选流存在。
例如,业务中可能存在许多需要部门领导审批的事情,但是领导审批的流程是很相似的,这时可以做成泛化关系表示:
上面是我参考的一篇文章,觉得将三种关系的区别讲得很清晰,在此基础上结合自己的系统,对项目(在线购物系统)的用例做了整体的描绘。
*****************************************************************
(1)系统整体用例图
按照先整体用例,后子系统用例来进行描绘的,欢迎大家提出好的建议!
转:UML中扩展和泛化的区别
泛化表示类似于OO术语“继承”或“多态”。UML中的Use Case泛化过程是将不同Use Case之间的可合并部分抽象成独立的父Use Case,并将不可合并部分单独成各自的子Use Case;包含以及扩展过程与泛化过程类似,但三者对用例关系的优化侧重点是不同的。如下:
●泛化侧重表示子用例间的互斥性;
●包含侧重表示被包含用例对Actor提供服务的间接性;
●扩展侧重表示扩展用例的触发不定性;详述如下:
既然用例是系统提供服务的UML表述,那么服务这个过程在所有用例场景中是必然发生的,但发生按照发生条件可分为如下两种情况:
⒈无条件发生:肯定发生的;
⒉有条件发生:未必发生,发生与否取决于系统状态;
因此,针对用例的三种关系结合系统状态考虑,泛化与包含用例属于无条件发生的用例,而扩展属于有条件发生的用例。进一步,用例的存在是为Actor提供服 务,但用例提供服务的方式可分为间接和直接两种,依据于此,泛化中的子用例提供的是直接服务,而包含中的被包含用例提供的是间接服务。同样,扩展用例提供的也是直接服务,但扩展用例的发生是有条件的。
另外一点需要提及的是:泛化中的子用例和扩展中的扩展用例均可以作为基本用例事件的备选择流而存在。
识别用例之间的关系
用例间的三种关系:
(1)扩展(extends):用例B extends 用例A,表示用例B是用例A在某种特定情况下可能会出现的扩展用例。例如:老王进城办事,2小时就可以回去,在这2小时内内急时就会去上厕所。上厕所用例是进城用例的扩展,因为不上厕所老王进城办事也可完成。
(2)包含(includes):用例A includes 用例B,表示没有了用例B,用例A本身也
就不完整了。例如:还是老王进城,他从海南来北京办事,3天才能回去,那么这种情况下进城用例与上厕所用例的关系就应该是包含关系了。
(3)泛化:泛化关系指的是同一业务目的的不同技术实现。例如:老王进城,他可以坐飞机,可以坐火车,还可以走路,那么进城用例就泛化为坐飞机、坐火车和走路三个用例了,它们之间存在层级关系。
总的来看,扩展可以“冻结”基本用例以保持稳定(因为扩展用例通常是不确定的);包含可以提供公共交互,提高“复用”;泛化是同一业务目的的不同技术实现。用例之间除了上述三种关系不再有其他关系,用例之间不能通讯。
======================================================
下面是另外一种解释,用例子来描述。
4.2 用例之间的关系
用例描述的是系统外部可见的行为,是系统为某一个或几个参与者提供的一段完整的服务。从原则上来讲,用例之间都是并列的,它们之间并不存在着包含从属关系。但是从保证用例模型的可维护性和一致性角度来看,我们可以在用例之间抽象出包含(include)、扩展(extend)和泛化 (generalization)这几种关系。这几种关系都是从现有的用例中抽取出公共的那部分信息,然后通后过不同的方法来重用这部公共信息,以减少模型维护的工作量。
4.2.1 包含(include)
包含关系是通过在关联关系上应用< 包含关系是UML1.3中的表述,在UML1.1中,同等语义的关系被表述为使用(uses),如下图。 在ATM机中,如果查询、取现、转帐这三个用例都需要打印一个回执给客户,我们就可以把打印回执这一部分内容提取出来,抽象成为一个单独的用例\"打印回执\",而原有的查询、取现、转帐三个例都会包含这个用例。每当以后要对打印回执部分的需求进行修改时,就只需要改动一个用例,而不用在每一个用例都作相应修改,这样就提高了用例模型的可维护性。 在基础用例的事件流中,我们只需要引用被包含用例即可。 查询-基本事件流 1. 用户插入信用卡 2. 输入密码 3. 选择查询 4. 查看帐号余额 5. 包含用例\"打印回执\" 6. 退出系统,取回信用卡 在这个例子中,多个用例需要用到同一段行为,我们可以把这段共同的行为单独抽象成为一个用例,然后让其他的用例来包含这一用例。从而避免在多个用例中重复性地描述 同一段行为,也可以防止该段行为在多个用例中的描述出现不一致性。当需要修改这段公共的需求时,我们也只需要修改一个用例,避免同时修改多个用例而产生的不一致性和重复性工作。 有时当某一个用例的事件流过于复杂时,为了简化用例的描述,我们也可以把某一段事件流抽象成为一个被包含的用例。这种情况类似于在过程设计语言中,将程序的某一段算法封装成一个子过程,然后再从主程序中调用这一子过程。 4.2.2 扩展(extend) 扩展(extend)关系如下图所示,基础用例(Base)中定义有一至多个已命名的扩展点,扩展关系是指将扩展用例(Extension)的事件流在一定的条件下按照相应的扩展点插入到基础用例(Base)中。对于包含关系而言,子用例中的事件流是一定插入到基础用例中去的,并且插入点只有一个。而扩展关系可以根据一定的条件来决定是否将扩展用例的事件流插入基础用例事件流,并且插入点可以有多个。 例如对于电话业务,可以在基本通话(Call)业务上扩展出一些增值业务如:呼叫等待(Call Waiting)和呼叫转移(Call Transfer)。我们可以用扩展关系将这些业务的用例模型描述如下。 在这个例子中,呼叫等待和呼叫转移都是对基本通话用例的扩展,但是这两个用例只有在一定的条件下(如应答方正忙或应答方无应答)才会将被扩展用例的事件流嵌入基本通话用例的扩展点,并重用基本通话用例中的事件流。 值得注意的是扩展用例的事件流往往可以也可抽象为基础用例的备选流,如上例中的呼叫等待和呼叫转移都可以作为基本通话用例的备选流而存在。但是基本通话用例已经是一个很复杂的用例了,选用扩展关系将增值业务抽象成为单独的用例可以避免基础用例过于复杂,并且把一些可选的操作独立封装在另外的用例中。 4.2.3 泛化(generalization) 当多个用例共同拥有一种类似的结构和行为的时候,我们可以将它们的共性抽象成为 父用例,其他的用例作为泛化关系中的子用例。在用例的泛化关系中,子用例是父用例的一种特殊形式,子用例继承了父用例所有的结构、行为和关系。在实际应用中很少使用泛化关系,子用例中的特殊行为都可以作为父用例中的备选流存在。 以下是一个用例泛化关系的例子,执行交易是一种交易抽象,执行房产交易和执行证券交易都是一种特殊的交易形式。 用例泛化关系中的事件流示例如下: 因篇幅问题不能全部显示,请点此查看更多更全内容