我让自己疯狂了多少本书自相矛盾。
Class A {} class B {void UseA(A a)} //some say this is an association,
no reference is held but communication is possible
Class A {} class B {A a;} //some say this is
aggregration, a reference is held
但是很多人说持有引用仍然只是一个关联,并且对于聚合他们使用列表 - 恕我直言这是相同的,它仍然是一个参考。
我很困惑,我想了解这个问题。
E.g。这里:http://aviadezra.blogspot.cz/2009/05/uml-association-aggregation-composition.html - 强关联和聚合之间有什么区别,在这两种情况下,作者使用一个字段来存储引用。
另一个例子: 这据说是协会:
据说这是聚合:
public class Professor {
// ...
}
public class Department {
private List<Professor> professorList;
// ..
}
再次,有什么区别?它是两种情况下的参考
答案 0 :(得分:3)
这个问题已经并且将会在许多不同的变体中多次被问到,因为很多人,包括许多知名的开发人员,都对这些术语的含义感到困惑,这些术语已在UML中定义。由于这个问题已被多次询问,因此也经过多次回答。见,例如, this answer。我将尝试总结UML定义。
两个类之间的关联不是通过方法参数建立的,而是通过引用属性(类属性)建立的,其范围/类型是关联的类。如果方法参数的类型是类,则不会建立关联,而是依赖关系。
在查看关联的逻辑概念之前,首先要了解它们的逻辑概念。对象类型之间的关联对这些类型的对象之间的关系进行分类。例如,关联Committee
- has - ClubMember
- as-chair,在下图所示的类图中可视化为连接线,可以对FinanceCommittee-has-PeterMiller-as-chair的关系进行分类,RecruitmentCommittee-has-SusanSmith-as-chair-advisoryCommittee-has-SarahAnderson-as-chair,其中对象PeterMiller,SusanSmith和SarahAnderson属于ClubMember
类型,对象FinanceCommittee,RecruitmentCommittee和AdvisoryCommittee属于{ {1}}。
关联始终通过引用属性进行编码,其范围/类型是关联类。例如,像这样
Committee
在UML中,聚合和组合被定义为具有对部分 - 整体关系进行分类的预期含义的特殊关联形式。在聚合的情况下,与组合相反,整体的部分可以与其他整体共享。下面的聚合示例说明了这一点,其中一个课程可以属于许多学位课程。
合成的定义特征是具有独占(或不可共享)部分。组合物可能在整体与其部分之间存在生命周期依赖性,这意味着当整体被破坏时,其所有部分都会被破坏。然而,这仅适用于某些组合情况,而不适用于其他情况,因此它不是一个定义特征。组件(组件)可以从整体(复合材料)分离并因此在其破坏后存活的组合物的示例如下:
答案 1 :(得分:1)
参见上层建筑2.1.1:
关联可以表示复合聚合(即,整体/部分关系)。只有二元关联可以是聚合。复合聚合是一种强大的聚合形式,需要一次将一个实例包含在最多一个复合中。如果删除了复合,则通常会删除它的所有部分。请注意,在删除复合之前,可以(在允许的情况下)从复合中删除零件,因此不会将其作为复合的一部分删除。组合物可以在具有传递性缺失特征的有向无环图中连接;也就是说,删除图形的一部分中的元素也将导致删除该元素下面的子图的所有元素。组合由关联的部分末端的isComposite属性表示为true。
可导航性意味着可以从参与关联另一端的链接的实例有效地访问在运行时参与链接的实例(关联实例)。实现此类访问的精确机制是特定于实现的。如果一端不可导航,则可能会或可能不会从其他端进行访问,如果是,则可能效率不高。请注意,不会阻止在UML模型上运行的工具从非导航端导航关联。
您的上述示例位于不同的抽象级别。 Department
/ Course
是具体的编码类,而Department
/ Professor
处于某种抽象业务级别。虽然没有很好的来源(我知道)解释这个事实,composition
和aggregation
是您将仅在业务级别使用的概念,几乎从不在编码级别(下面的例外)。当您处于代码级别时,Association
双方都有角色名称,您的生活会更好。角色本身是一个不同的(/冗余!)渲染类的属性,引用相反的类。
使用聚合作为类之间的强绑定,例如在数据库建模中。只有在以前删除了所有聚合时,才能删除主服务器(或者反之:删除主服务器将强制删除聚合)。聚合不能独立存在。你的例子中的组合是(来自我的POV)一个愚蠢的结构,因为它假装是一周的聚合。但那简直就是胡说八道。然后使用关联。只有在业务层面,您才可以尝试将机器零件建模为复合零件。在具体层面上,构图是一个无用的概念。
TL;博士;
如果类之间存在关系,则将其显示为简单关联。在讨论域详细信息时,添加角色等细节将有所帮助仅在业务级别建模时才鼓励使用组合/聚合,并在代码级别上禁止使用组合/聚合。
答案 2 :(得分:1)
我写了一篇关于UML Association vs Aggregation vs Composition基于实际UML规范而不是书籍作者解释之间差异的文章。
主要结论是
简而言之,组合是一种具有实际约束和对发展的影响的关联,而聚合纯粹是协会性质的功能性指示,没有技术影响。
Navigability是一个完全不同的属性,独立于AggregationKind。
答案 3 :(得分:0)
首先,UML是一种丰富的语言,这意味着描述相同内容的方法不止一种。这就是你找到不同书籍中描述的不同方式的一个原因(以及SO上的冲突答案)。
但关键问题是UML和源代码之间的巨大断开连接。如何在UML中表示特定的源代码构造,反之亦然,根本不是UML规范的一部分。据我所知,只有一种语言(Java)具有官方UML配置文件,而且已经过时了。
因此,特定源语言结构的表示留给工具供应商,因此不同。如果您打算从模型生成代码,则必须遵循供应商的约定。相反,如果您希望从现有源代码生成模型,则可以获得基于这些相同约定的模型。但是如果你将这个模型转移到另一个工具(这在最好的时候很难)并生成代码,你将不会得到相同的代码。
在语言和工具不可知模式中,我可以找到在哪些情况下可以使用的关系here。值得重复的一点是,我不在源代码模型中使用无向关联,正是因为它们在实际代码中没有明显的对应关系。如果在代码类A中有一个对B类的引用,而B也有一个到A,那么我会改为绘制两个关系。