UML类图中5中关系的辨析(修订)
Figure 1. UML offers five different types of class relationship
要理解这5中关系就不能简单的把它们和具体的语言实现相关联,UML介于问题域和解域之间,因而兼有这两者的概念。虽然类图是静态的,但类之间的这5种关系却是动静兼有的(也就是编译时和运行时混合的)。
问题域、解域混合,编译时、运行时混合是这5种关系的特点。
问题域
解域
编译时
运行时
Dependencyusesa短暂的或者对非业务类的(如工具类)依赖
作用域在方法内部的reference(可能是方法参数或方法内部声明的reference)作用域在方法内部的reference(可能是方法参数或方法内部声明的reference)短暂的
Associationhasa相对固定的,对业务类的依赖
类属性类属性持续一定时间的
Aggregationownsbutmayshareownsbutmayshare类属性类属性生命线可能相关联
Compositionispartofispartof类属性类属性生命线总是关联
Generalizationisatypeofisatypeof继承
继承
Dependency依赖:uses a
Dependency表示一个类uses或者知道另一个类。一方的改动将引起另一方的改动。这是一种典型的临时关系,代表了类之间的一种短暂的交互。
针对“一方的改动将引起另一方的改动”这句话来讲,所有强于dependency的关系都蕴含/隐含者dependency关系 。且这个意义常用来表示package之间的依赖关系。(package之间只有依赖和继承2种关系)
因为是一种短暂的关系,所以依赖类指向目标类的reference的作用域一般在一个方法的内部(这有可能是方法的传入参数或者在方法内部声明的reference),而不是 类的属性。因为属性代表一种相对持久的关系,而方法内部的对象,只有在方法被调用时(短暂的)才与依赖类(方法所在的类)发生关系。比如window和 event之间,只有用户事件时两者才会发生关联,当没有事件时两者并不一起工作,他们之间的合作关系是短时间的。我们也不会把event声明为 windows的一个属性,而一般在windows的方法里进行处理。
Dependency 还经常用于表示一种对通用模块(如java.util.regex ,java.math )而非业务模块的依赖关系。这显然是一种问题域(而不是解域或技术角度)的思维角度。
Association关联:hasa
Associations表示类之间的一种持续一段时间的合作关系,但被关联的2者生命线(顺序图的概念)不被绑定(也就是说如果一个类被销毁,另一个类不一定被销毁)。
在具体实现时往往表示为类的属性。但也不是所有的属性都是Associations,像int/bool这类的属性就不易表示为Associations。
关联是可以有导航的,就是可以有方向,用带箭头的实线表示。
Aggregation聚合:ownsbutmayshare
Aggregation 表示一种owns(拥有)关系,并且 被关联的2者生命线可能 被关联。在UML规范中对这种关系的定义非常模糊,充斥这也许、可能这类字眼。《UML Distilled》中甚至说“聚合是完全没有意义的。因此,我建议,你在自己的的图中略去聚合。”
我个人也认为Aggregation 是较难判断的一类关系,很难确切定义它。它的上面association和下面composition的定义都很明确,大概可理解为介于两者之间,但偏composition。
Composition组合:ispartof
Composition用于表示“整体-部分”关系。这种关系是“非共享”的,也就是说,在任何时间,“部分”只能包含在一个“整体”中。二者的生命线总是相连的,如果整体被销毁了,部分也就不存在了。
这里的“部分”不一定是多个。
这里要提醒一下,这里的“非共享”关系指的是实例,而不是类。就是说一个类的不同实例可以属于不同的拥有者,但一个特定的实例只能有一个拥有者。
Generalization 泛化(Otherwise Known as Inheritance): is a type of
以上5类关系依赖性由弱到强。
比较常用的是association/composition/generalization
以下是相关概念的英文表述:
Dependency between classes means that one class uses, or has knowledge of, another class. It is typically a transient relationship, meaning a dependent class briefly interacts with the target class but typically doesn't retain a relationship with it for any real length of time.
A dependency implies only that objects of a class can work together.The dependency relationship is often used when you have a class that is providing a set of general-purpose utility functions, such as in Java's regular expression (java.util.regex ) and mathematics (java.math ) packages. Classes depend on the java.util.regex and java.math classes to use the utilities that those classes offer.
Associations are stronger than dependencies and typically indicate that one class retains a relationship to another class over an extended period of time. The lifelines of two objects linked by associations are probably not tied together (meaning one can be destroyed without necessarily destroying the other).Association means that a class will actually contain a reference to an object, or objects, of the other class in the form of an attribute.
Aggregation is a stronger version of association. Unlike association, aggregation typically implies ownership and may imply a relationship between lifelines.
Composition is used to capture a whole-part relationship. The "part" piece of the relationship can be involved in only one composition relationship at any given time. The lifetime of instances involved in composition relationships is almost always linked; if the larger, owning instance is destroyed, it almost always destroys the part piece.
参考文献
1.O'Reilly.Learning.UML.2.0.Apr.2006
2.O'Reilly.UML.2.0.in.a.Nutshell.Jun.2005
3.UML Distilled 3rd edition
4.道法自然:面向对象实践指南
ps:本想收藏,可是想到收藏和记录总是有些不太一样,所以重新作为文章发出.