
本文澄清 uml 标准演进中组合(composition)与聚合(aggregation)的关系本质,指出“组合是聚合的子集”属于 uml 2.5 之前的历史性误解;现行标准中二者是并列的、语义正交的聚合类型,分别对应 `composite` 和 `shared` 枚举值。
在面向对象建模与 UML 类图实践中,组合(Composition)与聚合(Aggregation)常被初学者混淆,尤其当某些教程图示(如 AlgoDaily 所展示的)将 Composition 明确画作 Aggregation 的一个子集时,更易引发概念误读。这种图示并非反映当前 UML 规范,而是遗留自早期 UML 版本(如 UML 1.x)中模糊且未严格形式化的语义约定。
根据 UML 2.5 规范第 110 页(Section 11.2.3, “AggregationKind”),Aggregation 是 Property 元素的一个枚举型属性,其合法取值仅有三个:
none — 无聚合语义(默认) shared — 表示共享聚合(Shared Aggregation) composite — 表示组合(Composite Aggregation)
关键在于:shared 与 composite 是同一层级的互斥选项,并非继承或包含关系。规范明确指出:
“shared indicates that the Property has shared aggregation semantics. Precise semantics of shared aggregation varies by application area and modeler.”“composite indicates that the Property is aggregated compositely, i.e., the composite object has responsibility for the existence and storage of the composed objects.”
这意味着:
- composite 具有强生命周期约束:整体(composite)销毁时,部分(parts)必须随之销毁;部分不能同时属于多个整体;通常体现为“拥有权”和内存管理责任(如 C++ 中 std::unique_ptr 或 Java 中私有字段的 new 实例)。
- shared 则无标准化语义:它不强制任何生命周期依赖,仅暗示一种“松散的‘拥有’关系”,例如一个 Department 持有对若干 Employee 的引用,但员工可同时属于项目组或工会——此时建模者需自行约定含义,工具和代码生成器通常忽略该标记。
因此,将 Composition 视为 Aggregation 的“子集”,本质上是将 composite 错误理解为 shared 的特化形式。而 UML 2.5 已彻底解耦二者:它们同属 AggregationKind 枚举,地位完全平等。所谓“历史原因”,是指 UML 1.x 曾尝试用 aggregation="shared" 作为基类,再派生 aggregation="composite",但因语义不清晰、缺乏可操作性而被废弃。
✅ 正确实践建议:
- 在类图中,优先使用标准符号:空心菱形(◇)表示 shared,实心菱形(◆)表示 composite,二者不可混用或嵌套标注;
- 编程实现时,勿依赖 shared 做任何自动化行为(如 GC 策略或序列化逻辑);仅 composite 可合理映射为强所有权(如 RAII、@PreDestroy 回调、CascadeType.ALL);
- 若团队协作建模,应在设计规范中明确定义 shared 的业务含义(例如:“表示逻辑归属,非内存归属”),避免歧义。
总结而言,组合不是聚合的一种,而是与聚合(即共享聚合)并列的、语义更严格的另一种聚合形式。理解这一演进,有助于写出符合现代 UML 规范、可被主流工具(如 Enterprise Architect、StarUML、PlantUML)准确解析的高质量模型。










