include and extend

 

对于include和extend 还是有些混淆。

虽然很多书籍和文章讲解了UML图中的include和extend区分,但多数讲的让人看了似懂非懂的,在实际运用中仍然会遇到不少困难,是否有通俗易懂的讲述了?请大家在这里交流一下,我自己先说一下我的理解:include主要是用例重用,所以通常至少有两个用例包含共同的一个用例,如:
A include B,并且C include B,角色通常只直接作用在包含另一用例的用例上,在本示例中,角色只作用在A和C上,而不会直接作用于B上,这里的B不直接面向观众,而A直接面向观众,可以看作C++的一个内部私有函数,B的存在只是为了代码重用,当然这里是指用例重用;
而extend关系角色通常同时作用在扩展和被扩展用例上,如:A extend B,则角色即会直接作用于A也会直接作用于B,在这里可以看出A和B存在一个可选关系,A和B直接面向观众,这里A和B都是C++中的一个公有函数。
 
我的理解是extend其实也是一种include,但对于extend时include含义被弱化了,假设B extend A,则B应当是包含了A的逻辑的,但对于actor来说,B和A都是两个独立的逻辑,也就是说actor选择执行A或B是可以选择的,他可以选择A或者B,但在选择B时,实际上隐含执行了A,但对于include则不一样,同样假如B include A,则actor只能执行B,则不能去选择执行A而不执行B。

 

 


以下来自另一篇文章:

 

共性: 都是从现有的用例中抽取出公共的那部分信息,作为一个单独的用例,然后通后过不同的方法来重用这个公共的用例,以减少模型维护的工作量。



1
 、包含(include)

 

    包含关系:使用包含(Inclusion )用例来封装一组跨越多个用例的相似动作(行为片断),以便多个基(Base )用例复用。基用例控制与包含用例的 关系,以及被包含用例的事件流是否会插入到基用例的事件流中。基用例可以依赖包含用例执行的结果,但是双方都不能访问对方的属性。 

   
包含关系对典型的应用就是复用,也就是定义中说的情景。但是有时当某用例的事件流过于复杂时,为了简化用例的描述,我们也可以把某一段事件流抽象成为一个被包含的用例;相反,用例划分太细时,也可以抽象出一个基用例,来包含这些细颗粒的用例。这种情况类似于在过程设计语言中,将程序的某一段算法封装成一个子过程,然后再从主程序中调用这一子过程。  

   例如:业务中,总是存在着维护某某信息的功能,如果将它作为一个用例,那新建、编辑以及修改都要在用例详述中描述,过于复杂;如果分成新建用例、编辑用例和删除用例,则划分太细。这时包含关系可以用来理清关系。

 

2 、扩展(extend)

扩展关系:将基用例中一段相对独立并且可选的动作,用扩展(Extension )用例加以封装,再让它从基用例中声明的扩展点(Extension Point )上进行扩展,从而使基用例行为更简练和目标更集中。扩展用例为基用例添加新的行为。扩展用例可以访问基用例的属性,因此它能根据基用例中扩展点的当前状态来判断是否执行自己。但是扩展用例对基用例不可见。

 

 

 

对于一个扩展用例,可以在基用例上有几个扩展点。   

例如,系统中允许用户对查询的结果进行导出、打印。对于查询而言,能不能导出、打印查询都是一样的,导出、打印是不可见的。导入、打印和查询相对独立,而且为查询添加了新行为。因此可以采用扩展关系来描述:

  

3 、泛化(generalization)

 

泛化关系:子用例和父用例相似,但表现出更特别的行为;子用例将继承父用例的所有结构、行为和关系。 子用例可以使用父用例的一段行为,也可以重载它。父用例通常是抽象的。在实际应用中很少使用泛化关系,子用例中的特殊行为都可以作为父用例中的备选流存在。

例如,业务中可能存在许多需要部门领导审批的事情,但是领导审批的流程是很相似的,这时可以做成泛化关系表示: 

 

 

 

第三个

最近上论坛,看到在争论 Use Case 中 include 与 extend 的区别。其实这两者是很容易区分的。

include 是指用例中的包含关系,通常发生在多个用例中,有可以提取出来的公共部分(就象提取公因式一样),例如 UseCaseA 中包括了 a 和 b 两个流程,而 UseCaseC 中包含了 c 和 b 两个流程。为了提高复用性,可以把 b 提取出来,形成另一个用例 UseCaseB,此时,UseCaseA include UseCaseB(表现为一条指向 UseCaseB 的虚线,箭头在 UseCaseB 侧),UseCaseC 也 include UseCaseB。因而,当有 include 关系时,被 include 的用例通常会被两个以上的其他用例 include(否则就不需要重用,也就不需要提取出来了),用例图如下:



在 include 关系中,“UseCaseA 和 UseCaseC 知道 UseCaseB 的存在,而 UseCaseB 根本不知道有 UseCaseA 和 UseCaseC);

extend 则恰好相反。假设 UseCaseA 的功能描述为“发送一条通知”,可是,发送通知的方式可能有许多种,例如通过邮件发送、通过短信发送等。在需求分析阶段,可能无法明确到底有多少种方式,在用例分析阶段,UseCaseA 需要留出扩展接口,然后把已知的发送方式作为扩展用例给出,例如 UseCaseB 是“通过短信发送”,而 UseCaseC 是“通过邮件发送”,此时,UseCaseB 和 UseCaseC extend 了 UseCaseA,表现为两根虚线,箭头指向 UseCaseA,用例图如下:



在 extend 关系中,UseCaseA 不知道 UseCaseB 和 UseCaseC 的存在,但 UseCaseB 和 UseCaseC 却是知道 UseCaseA 并且知道如何在 UseCaseA 中作扩展的。

另:在用例图中,有时会看到两个用例之间有依赖关系(表现为一条单向或双向的实线),这是错误的,说明用例没有提纯。



也许有人会问“如果两个用例之间,一个要调用另一个时,怎么办?”(有可能是混淆了用例和模块的关系),那么,首先要区分概念,用例就是用例,用例不是模块,也不是组件(虽然一个用例能发展成为“一个或多个”模块或组件);其次,从用例分析的角度来看,如果用例 A 确实要调用到用例 B,那么,可以进一步分析:A 是调用了 B 的所有流程呢,还是其中一部分流程?
(1)如果是调用了一部分,此时可以把 B 中的那部分流程提取出来,形成用例 C,然后 A 和 B 都 include C;
(2)如果是调用了所有流程,那么,A 直接 include B 即可;
(3)如果 A 没有调用 B 中的任何流程……faint,那还画那条代表依赖的实线干嘛?

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值