如何在UML中表示双向关联及不同类型的聚合关系?
UML类图四种聚合/组合场景表示规范
先明确核心符号约定,方便理解不同场景的区分逻辑:
- 单向/双向关联区分:单向关联为带开放箭头的实线,箭头指向被引用的类,仅箭头起点的类持有另一端的引用;双向关联为无箭头的实线,两端的类互相持有对方的引用,是否带箭头是单向/双向的核心区分标志,和两端是否标注多重度无关
- 共享聚合(aggregation):整体类一侧用空心菱形标记,代表部分实例可以脱离整体独立存在
- 组合聚合(composition):整体类一侧用实心菱形标记,代表部分实例的生命周期完全和整体绑定,整体销毁时部分实例也会随之销毁
- 多重度标注在关联线的两端,代表当前位置对应的类实例的数量范围
1. 单向共享聚合
代码实现
class Foo { // 可持有0到多个Bar实例 ArrayList<Bar> bars = new ArrayList<>(); void addBar(Bar bar) { bars.add(bar); } } class Bar {}
UML表示说明
- 关联线从Foo指向Bar,带指向Bar的开放箭头,标识单向关联,仅Foo可以访问持有的Bar实例,Bar不知道Foo的存在
- Foo一侧标注空心菱形,标识共享聚合
- 多重度:靠近Foo侧标
0..*(一个Bar实例可以被0到多个Foo持有),靠近Bar侧标0..*(一个Foo实例可以持有0到多个Bar实例)
2. 双向共享聚合
代码实现
class Foo { // 可持有0到多个Bar实例 ArrayList<Bar> bars = new ArrayList<>(); void addBar(Bar bar) { bars.add(bar); bar.setFoo(this); } } class Bar { Foo foo; void setFoo(Foo foo) { this.foo = foo; } }
UML表示说明
- 关联线无箭头,标识双向关联,Foo可以访问持有的Bar,Bar也可以访问自己绑定的Foo
- Foo一侧标注空心菱形,标识共享聚合
- 多重度:靠近Foo侧标
0..1(一个Bar实例最多绑定1个Foo),靠近Bar侧标0..*(一个Foo实例可以持有0到多个Bar实例)
3. 单向组合聚合
代码实现
class Foo { // 可持有0到多个Bar实例 ArrayList<Bar> bars = new ArrayList<>(); void addBar() { bars.add(new Bar()); } } class Bar {}
UML表示说明
- 关联线从Foo指向Bar,带指向Bar的开放箭头,标识单向关联,仅Foo可以访问持有的Bar实例
- Foo一侧标注实心菱形,标识组合聚合,Bar实例完全由Foo内部创建,不会暴露给其他类持有,Foo销毁时所有关联的Bar实例也会被销毁
- 多重度:靠近Foo侧标
1(一个Bar实例只能属于1个Foo),靠近Bar侧标0..*(一个Foo实例可以持有0到多个Bar实例)
4. 双向组合聚合
代码实现
class Foo { // 可持有0到多个Bar实例 ArrayList<Bar> bars = new ArrayList<>(); void addBar() { bars.add(new Bar(this)); } } class Bar { // 原代码笔误,应为Foo类型而非Bar类型 Foo foo; Bar(Foo foo) { this.foo = foo; } }
UML表示说明
- 关联线无箭头,标识双向关联,Foo可以访问持有的Bar,Bar也可以访问自己绑定的Foo
- Foo一侧标注实心菱形,标识组合聚合,Bar实例创建时就和Foo绑定,生命周期完全依附Foo
- 多重度:靠近Foo侧标
1(一个Bar实例只能属于1个Foo),靠近Bar侧标0..*(一个Foo实例可以持有0到多个Bar实例)
内容的提问来源于stack exchange,提问作者aiwl
相关产品推荐
相关产品推荐

