Dependency, Association, Aggregation & Composition的四种区别

 

UML Class Diagram 体现 Class 之间的关系,Generalization 和 Realization,这两种非常常见,Java 编程语言对应extends 和 implements,余下的还有四种,分别是:Dependency, Association, Aggregation, Composition。
在余下的四种关系中 Dependency 是比较容易识别:

They (Dependency Relationships) are not implemented with member variables at all. Rather they might be implemented as member function arguments.

– Robert C. Martin, UML Tutorial: Part 1 — Class Diagrams

翻译:他们(依赖关系)根本不是使用成员变量去实现(操作)。而会是以成员函数的参数形式实现(操作)。

根据上面的表述,很容易发现Dependency的关键点在于成员函数的参数。在这里又要注意一个概念,依赖注入,这个和依赖是不同的,依赖注入是通过参数注入的方式,来实现内聚等功能,来达到使用成员变量去实现的目的。
继续看 Association, Aggregation, Composition,单纯从理论上看,这三种关系的区别还算清晰,但是到目前为止,我还无法将它们从实现代码上把它们区分开来。

Aggregation denotes whole/part relationships whereas associations do not. However, there is not likely to be much difference in the way that the two relationships are implemented. That is, it would be very difficult to look at the code and determine whether a particular relationship ought to be aggregation or association.

– Robert C. Martin, UML Tutorial: Part 1 — Class Diagrams

翻译:Aggregation表示整体/部分关系,而associations不是。然而,在实现这两种关系的方式上却没有多大差别。光从代码角度去确定一个特殊关系应该是aggregation或是association是非常难的。

从理论上讲,Aggregation 和 Association 的区别在于前者强调的是整体和部分的关系,但这在代码上是很难区分的。

Composition 和 Aggregation 的区别在于前者强调 lifetime,就是由我才有你。

有了这个基础,我们看个例子

1. Dependency – Person and his Keys. – 当人要开门的时候,执行开门这个动作(函数),并出入特定的钥匙(参数),并且没有把钥匙看作是人的类中的一个成员变量。
2. Association – Credit Card and Person. – 一个人可以有信用卡,也可以没有信用卡,信用卡对于一个人来说可有可无,而且更称不上人的一部分。has的关系
3. Aggregation – Order and Order Lines. – 订单(Order)是订单处理流(OrderLine)所必需的一部分。没有Order的话,OrderLine就没有了实际意义。同时这个Order可能属于多种不同的OrderLine。
4. Composition – Human Body.  – 人的身体,是一个人的一部分,并且不可能属于其他人,只是自己。has关系

 

Dependency与Aggregation、Association和Composition的角色分析。

Dependency是一种外界(B类)如何对内部(A类)影响的方式(也可以说进入的方式)。

而后面三种是外界(B类)与内部(A类)的关系。

 

 接下来看下面的图

 

UML Class Diagrams 实例

上图纤细标明了各类间的关系。其中Car和Petrol的关系,我个人觉得应该是一个Aggregation关系。同时,我对于其中他将Country作为Family的Composition我也觉得不妥。但是具体怎么设计关键还是看当事人对类的理解。按照上图的理解是一个家庭可具有属性为0..1个人,一个国家可具有属性为1…*个家庭。把菱形念成“具有属性为”,把的数字认为是最近的那个类的个数。这里就是1个(这个一个是隐含体现在途中的) 家庭 可具有属性为 多个  。

 

单箭头和无箭头,单箭头表示单项,无箭头表示双向


最后来一个个人觉得最精辟的解释(园子里看到的):

两个类之间的关系,例如类A和B。
如果是B是A成员变量,而且BA的构造函数中生成(new),那么就是Composition。

(解释:因为Composition是强相关与整体的东西,也就是说不和构造函数一起new出来的话,那么new出来的那个类是不完整的。(比如Person的HumanBody,不new Body怎么会是正常人。))
如果是B是A成员变量,而且B不在A的构造函数中生成(new),而是在有需要的时候才new,那么就是Aggregation。

(解释:这里体现的概念是和上面不同的,Aggregation的东西,是表示与new出来的类是松散关系的,不影响他的有无。(比如Person的Credit Card,不new Credit Card还是人))
如果A在某个函数中使用了B作为局部变量,那么就是Dependency。

(解释:这只是种方式,比如我可以作为构造函数的参数传入,那么就是Composition依赖注入,如果作为普通函数的参数,那么就有可能是Aggregation的依赖注入)

设计的时候是反过来,先决定这两个类之间的关系,在有编程语言的实现。





 » 订阅本站:RSS订阅

发表评论

您也可以使用微博账号登陆

无觅相关文章插件,快速提升流量