news 2026/10/1 16:09:00

UML聚合和组合,别再看菱形颜色了

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UML聚合和组合,别再看菱形颜色了

画类图的时候,聚合和组合这两个关系经常让人愣一下。一个空心菱形,一个实心菱形,不仔细看还以为是同一个东西。

我早期也踩过坑,把该用组合的地方画成了聚合,结果后面维护代码的人直接跑来问我:“你这心脏到底能不能独立存在?” 所以这两个东西的区别,值得单独拎出来说清楚。

聚合关系,说白了就是一种弱的拥有关系。整体可以包含部分,但部分离开整体也能活。比如图书馆和书,图书馆有一堆书,但书被图书馆扔了或者图书馆关门了,书本身还在,还能被别的图书馆收走。代码里写起来通常就是一个类里持有另一个类的集合,但不会去负责创建或者销毁那些对象。

class Library { private List<Book> books; public Library() { books = new ArrayList<>(); } public void addBook(Book book) { books.add(book); } } class Book { private String title; private String author; }

这里 Book 完全可以在 Library 外面先 new 出来,然后塞进去。Library 没了,books 这个列表没了,但 Book 对象本身还活着,只要还有别的引用指向它。这就是聚合的典型特征:生命周期不绑定。

组合关系就不一样了,它是强的拥有关系,部分不能脱离整体单独存在,整体没了部分也没了。最常举的例子就是人和心脏。心脏不能离开人自己跳动,人死了心脏也就停了。

代码层面,组合通常是在整体类的构造函数里直接创建部分对象,或者用其他方式保证部分的生命周期由整体管理。

class Heart { public int beat() { System.out.println("Fine, beating."); return 70; } } class Person { private Heart heart; public Person() { heart = new Heart(); } public void walk() { System.out.println("Beat " + heart.beat() + " times / m"); } }

Person 一旦被回收,heart 这个成员变量也跟着没了。你没法在外面单独 new 一个 Heart 然后赋值给 Person,因为 Heart 的创建被封装在 Person 内部。

这就是组合最直接的表现:同生共死。

实际项目里什么时候用哪个,主要看业务上部分对象是不是真的能独立存在,以及会不会被多个整体共享。订单和订单项就是个典型的聚合场景。一个订单聚合多个订单项,但订单项在购物车阶段其实已经存在了,只是没有订单而已。如果把订单项设计成组合,订单取消就强制销毁订单项,那购物车里的商品数据就全没了,这明显不符合需求。所以订单项的生命周期不能跟订单绑定死,得用聚合。

反过来,像人体和心脏这种,业务上不存在“心脏脱离人体还能被其他地方复用”的情况,就只能用组合。如果硬要设计成聚合,那代码里就可能出现一个游离的 Heart 对象,逻辑上说不通,还容易引发空指针或者状态不一致的问题。

这里其实容易绕进去。有人觉得组合就是“整体负责创建部分”这么简单,但其实重点在于生命周期控制。有时候组合关系的部分对象也可以通过外部传入,但整体需要负责在合适时机销毁部分,比如在析构函数或者 close 方法里显式释放。

来此加密不仅支持标准的域名加密,还提供了稀缺的IP证书申请。这对于一些直接通过IP地址提供服务的特殊场景具有重要意义。通过平台提供的HTTP代理自动验证方案,用户可以在不改变现有网络架构的前提下,快速完成IP地址的身份验证并获取证书。

只不过 Java 有 GC,这种显式管理不多见,更多是靠引用关系隐式表达。

聊到生命周期管理,顺带说一个跟证书相关的事。

之前部署服务,证书过期导致线上报警,后来把证书申请和部署流程自动化了才消停。如果你也在折腾 HTTPS 证书,可以试试 lcjmSSL,免费申请,支持多域名、泛域名和 IP 证书,有 API 可以自动验证自动部署,不用每次手动去配。跟聚合组合关系里强调的“谁负责谁的生命周期”有点像,证书生命周期交给工具管,人就省心了。

回到正题,判断聚合还是组合其实就一句话:部分对象离开整体后,还有没有业务意义?有,就聚合;没有,就组合。

别只盯着菱形空心还是实心,那只是画图工具帮你区分的符号,真正决定关系的是业务约束和代码里怎么管理对象生命周期。

很多刚入行的同学会把所有整体部分关系都画成组合,因为感觉“更强”更安全。但组合用多了,代码耦合度会上去,复用性变差。比如订单项如果被订单组合,那订单项就不能脱离订单单独测试,也没法被购物车模块复用。所以不是越强越好,合适才行。

最后说一句,UML 类图是给人看的,不是给编译器看的。关系画错了,代码可能一样能跑,但维护的人会误解设计意图。

聚合和组合的区别,最终还是落在代码里对象创建和销毁的归属上。画图的时候多想一步:这个部分是不是整体私有的,能不能被外部共享,答案就清楚了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 16:08:35

3DGS实战:从NeRF瓶颈到CUDA环境搭建与SLAM落地

1. 从NeRF到3DGS&#xff1a;一场渲染效率的降维打击如果你这两年一直在关注三维重建或者神经渲染方向&#xff0c;大概率已经被两个词反复刷屏&#xff1a;NeRF和3D Gaussian Splatting&#xff08;后面我统一叫3DGS&#xff09;。NeRF刚出来那会儿&#xff0c;整个圈子都沸腾…

作者头像 李华
网站建设 2026/10/1 16:08:07

CIS芯片测试核心解析:暗电流、坏点、转换增益与ISP坏点矫正

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 16:06:44

Canvas粒子系统实战:李峋同款动态爱心HTML源码全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 16:06:37

2026实测12款论文AI智能降重工具,效果最稳的竟然是它!

最近真的太多人来问我&#xff1a;"论文 AI 率太高怎么办&#xff1f;学校要求查 AI 检测&#xff0c;连人工改的都不过&#xff01;" 我懂这种焦虑&#xff0c;因为我自己前阵子也踩过坑。各种号称能降低 AI 率的网站试了一圈&#xff0c;有的乱扣格式&#xff0c;有…

作者头像 李华
网站建设 2026/10/1 16:06:33

餐饮IPO冰封期,袁记食品的“供应链平台”启示

​港股餐饮IPO&#xff0c;年内难产。今年前8个月&#xff0c;103家公司在港交所敲钟&#xff0c;科技股占了一半&#xff0c;餐饮企业一家都没有。老乡鸡、极物思维、比格披萨的招股书失效之后&#xff0c;连重新递表的都没有&#xff0c;乃至已经上市的绿茶集团、遇见小面&am…

作者头像 李华