组合:一个类可以引用其他类的对象作为成员。这被称为组合,有时被称为has-a关系。
Deitel P.J.,Deitel H.M. - Java如何编写第9版。
本主题讨论了这个观点: Prefer composition over inheritance?
成分:复合聚集(成分)是一种“强”聚合形式,具有以下特征:
*它是二元关联,
*这是一个整体/部分关系,
*一个部件最多可以包含在一个复合体(整体)中,并且
*如果复合(整体)被删除,其所有复合部分都会被“正常”删除。
在http://www.uml-diagrams.org/composition.html上找到 (实际上,Deitel在同一本书中提出了遵循这个想法的UML示例,但没有解释其中的差异)。
本主题讨论了这一观点:
What is the difference between association, aggregation and composition?
很好,两者都是正确的。这引入了同音词概念的问题。
例如:不要绘制带有组合箭头的UML模型来举例说明第一个定义:在UML中,任何关联都是由 Deitels'组成的第一个定义。
以下是我的问题的一些方面可能有助于正确答案:
我怎么说(也知道)我们在说什么作文?
我们在两个定义之间划线(在上下文中)?
我能说第一个是面向对象编程,第二个是软件工程/建模吗?
UML组合是否仅为模型概念/行话?
UML组合是UML专有的吗?或者也适用于编程领域?
如何在团队中避免误解“我们在谈论什么构成”?
请回答参考资料,证据,这不是哲学/意见问题,而是我试图解决的“范围”问题。
这不是“什么是作文”的问题。
编辑:我在想是否区分是动词x形容词:“编写”一个类(第一个def。)和“一个复合关系”(第二个def。)。
答案 0 :(得分:2)
我发现很难解释UML关联和实现引用之间的区别,但至少没有解释UML关联实际上是什么,以及它们可以做什么,所以我们走了。
让我们先看一下UML关联和链接(关联实例)是什么。
[11.5.3.1]关联指定了类型化实例之间可能出现的语义关系。
[11.8.1.1]链接是一个引用类型对象的值元组。关联对一组链接进行分类,每个链接都是关联的一个实例。链接中的每个值都指的是关联的相应末尾类型的实例。
以下是有限关联的有效实现。
class Brain { }
class Head { }
a = new Brain;
b = new Head;
link = (new Array).add(a).add(b);
[9.5.3]当一个Property通过ownedAttribute由一个分类器而非一个Association拥有时,它代表一个分类器的一个属性。
(注意:Class是分类器的子类。)
[11.5.3.1]由最终类所拥有的协会的最终财产或该协会的navigableOwnedEnd表示该协会可从相反的两端导航;否则,协会不能从相反的两端导航。可导航性意味着可以从Association的另一端的实例有效地访问在运行时参与链接的实例(关联的实例)。实现这种有效访问的精确机制是特定于实现的。如果一个终点不可导航,则可能会或可能不会从另一端进行访问,如果是,则可能效率不高。
为什么这些概念相关?想象一下下面的例子。
我们看到brain
是Head
类的属性(黑点表示相反类的所有权),并且它是可导航的(箭头)。
我们还看到head
不是Brain
的属性(没有黑点⇒不属于Brain类⇒不是Brain的属性),但它仍然是可导航的。这意味着在UML中,head
属性由关联本身保存。
例如,实现可能看起来像这样(关联本身由两个引用的元组表示(参见前面的 link 描述))。
class Head {
public Brain brain;
}
class Brain {
}
h = new Head;
b = new Brain;
h.brain = b;
link = (new Array).add(h).add(b);
因此,当你希望开始看到时,UML关联并不是一个简单的概念,而是一种关系。
让我们添加另一部分,组合。
[11.5.3.1]二元关联可以表示复合聚合(即,整体/部分关系)。组合由isComposite属性表示 [9.9.17]仅当聚合为复合时,isComposite的值才为真。
聚合为
- none - 表示该属性没有聚合语义。
- shared - 表示该属性具有共享聚合语义。共享聚合的精确语义因应用领域和建模者而异。
- 复合 - 表示属性是复合聚合的,即复合对象负责组合对象的存在和存储
我们再次看到,UML关联明确指定了很难从实现中感知的概念(例如,谁负责对象管理/销毁)。
因此,从上面的描述中我们可以构建一个更精确的描述实现组合(具有关系)。
[Deteils]组合:一个类可以引用其他类的对象作为成员。这被称为组合,有时被称为has-a关系。 麦康奈尔[代码完成2,6.3]也指有一种关系作为遏制。
然而,他们都没有谈论 HOW 对象(容器包含,作曲家复合)彼此相关,谁负责生命周期,或者包含的元素是否知道容器。
所以,只要说对象有一个has-a关系(并称之为组合),你实际上可能意味着任何这些(以及其他几个)
因此,如果你在编程中调用一些组合,你几乎可以指任何关系/引用(或者更确切地说不是继承),所以这个单词本身并不是很有用。
另一方面,在UML中,您试图捕获有关对象如何相互关联的所有此类信息。因此,专注于赋予术语更精确的含义。因此,当您在UML中调用某些组合时,您会想到一个非常具体的has-a关系,其中容器负责所包含项的生命周期。
所有这些额外的概念信息意味着甚至没有精确的方法来实现关联。这是有道理的,因为实现将取决于目标编程语言或环境(例如,可执行模型,其中UML概念被用作最终产品)。
作为一个例子,我可以推荐一篇描述Java中UML关联实现的文章,其中包含多重性,可导航性和可见性Implementing UML Associations in Java等强制概念。
我怎么说(并知道)我们在谈论哪种作文?
通过上下文,或者您可以问(当不确定时,这总是一件好事)。就我个人而言,我已经听过使用作曲作为"有一种关系"只有在区别于继承时;在其余的UML方面。但是我又在学术界,所以我的观点有偏见。
我们在两个定义之间划线(在上下文中)?
作为"编程"术语组成实际上并不代表任何东西(只有它是a-a),我建议你自己画线并推动其他人使用更精确的术语。
我能说第一个是面向对象编程,第二个是软件工程/建模吗?
或多或少,这个答案中提到的所有细微差别。
UML组合是否仅为模型概念/行话? UML组合是UML专有的吗?或者也适用于编程领域?
不,你可以在编程中使用它来表示UML中的含义,但你可能需要更明确地说明它。例如。 "这个类是这些类的复合,因为它管理它们的生命周期。"。 重点是教人们区分常规的有关系,以及具有更精确语义的关系。
如何避免错误传达"我们谈论的是什么构成"在团队中?
这是一个非常广泛的问题,您可以应用于您想要附加特殊含义的任何术语(甚至软件工程甚至是什么?),并且没有最佳方法。拥有团队共享词汇(您可能已经在您的域中拥有大量特定术语),并指导人们使用更精确的术语。
带编号的引号是指UML 2.5 Specifications中的部分。
答案 1 :(得分:0)
引用第110页的UML 2.5规范:
有时,属性用于模拟使用一个实例将一组实例组合在一起的情况;这称为聚合。为了表示这种情况,Property具有AggregationKind类型的聚合属性;表示整个组的实例由属性的所有者分类,表示分组个体的实例按属性的类型进行分类。 AggregationKind是一个枚举,具有以下文字值:
无:表示该属性没有聚合语义。
shared :表示该属性具有共享聚合语义。共享聚合的精确语义因应用领域和建模者而异。
复合:表示属性是复合聚合的,即复合对象负责组合对象的存在和存储(参见11.2.3中部分的定义)。
就我个人而言,我认为复合聚合的概念是关于对象生命周期的,而不是静态关系。 复合聚合会在其父级死亡时终止聚合成员。 无将此打开。并且共享聚合是OMG不应该引入的混蛋,因为它的语义是依赖于域的。