news 2026/9/8 3:09:05

后端开发三年,我才真正搞懂什么是“高内聚低耦合”

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
后端开发三年,我才真正搞懂什么是“高内聚低耦合”

刚入行的时候,我就知道“高内聚、低耦合”这六个字,面试时背得滚瓜烂熟。但说实话,真正理解它是什么、为什么要这样做,是在写了三年代码之后。

不懂的时候,以为只是抽象的概念

前两年写代码,我对这六个字的理解停留在字面意思上:高内聚就是把相关的东西放一起,低耦合就是少依赖别人。听起来很简单对吧?

那时候写代码的思路很简单:产品提了需求,我就在现有的Service里加方法,或者在Controller里直接处理新逻辑。Spring Boot的自动装配太方便了,@Autowired一加,哪里需要点哪里。一个Service类从最初的几百行,慢慢膨胀到上千行,订单逻辑、用户逻辑、库存逻辑、物流逻辑全搅在一起。

当时觉得这样没问题啊,代码能跑,功能正常,单元测试覆盖率也还可以。直到有一次产品需求变更,要调整订单状态的流转逻辑。我花了整整三天改代码,改完这一块,发现另一块逻辑不工作了。修好了那一块,又发现报表数据不对了。牵一发而动全身,改得我头皮发麻。

那一刻我才意识到:我的代码出了问题。可是问题在哪?我翻出设计模式的书,重新看到那六个字——高内聚、低耦合。之前是背下来的,这次好像有点感觉了,但又说不太清楚。

一个重构让我真正懂了

真正让我开窍的是一次重构。当时要把一个复杂的订单处理模块拆开,我尝试按职责把原来的大Service拆成几个独立的类:

OrderValidator——负责订单校验

OrderPriceCalculator——负责价格计算

OrderStatusManager——负责状态流转

OrderRepository——负责数据持久化

拆完之后发现,每个类做的事情变得特别清晰。改价格计算逻辑的时候,我只需要看OrderPriceCalculator这一个类,不用担心影响到状态流转。因为OrderStatusManager只依赖OrderRepository和几个外部接口的抽象,不依赖具体的价格计算实现。

这就是“高内聚”——一个类只做一类事,相关的数据和方法都封装在内部,对外只暴露必要的方法。产品改需求了,我能快速定位到要改哪个模块,而且改动范围可控,不怕改出连锁反应。也正因为模块之间依赖的是接口而不是具体实现,改价格算法时只需要换一个实现类注入进去就行,完全不用动OrderStatusManager的代码——这就是“低耦合”。

那一刻我明白了一件事:我以前是在一个巨大的Service里用“注释分区”假装模块化,但编译器根本不知道这些分区,改动时所有代码都在同一个文件里,彼此之间没有任何隔离。而真正的模块化,是用类和接口的边界做隔离。

理解后的三个判断标准

现在我看一个项目的代码质量,会用三个标准判断它是否符合高内聚低耦合的原则:

第一,改动一个功能时,需要改几个文件?如果需求变更是家常便饭,每次改动都涉及七八个甚至十几个文件,那耦合度一定高了。好的设计应该让90%的需求变更只影响一到两个模块。

第二,这个类我能用一句话说清楚它是干什么的吗?如果你只能用“它负责订单相关的所有事”来描述一个类,那它的内聚度一定不够。高内聚的类应该能用一句话精准描述它的单一职责。

第三,新同事上手改代码,敢不敢只改一个文件就提交?如果新同事每次改完都要问“我改了这里,会不会影响那里”,说明模块之间的边界不够清晰,耦合太紧。

这六个字到底在说什么

说到底,“高内聚、低耦合”这套原则,追求的不是代码本身的某种美学,而是——当变化发生时,你需要付出的代价有多小

商业世界里的需求永远在变,一个好的软件设计,不是把未来所有变化都预测到,而是让未来发生的变化尽可能被限制在局部,不会引起全局的连锁反应。高内聚保证了这个“局部”足够小且足够完整,低耦合保证了这些“局部”之间不会互相传染。

现在回过头看,那六个字从来不是背出来就完事的。它需要在一次次重构中、在一次次被需求变更折磨之后,才能真正刻进代码里。如果你现在还觉得它只是一句口号,可能只是因为——还没遇到那个让你头皮发麻的需求变更。

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

轻量剪贴板历史服务:解决KVM/RDP剪贴板丢失的本地方案

这次我们来看一个“随手做的剪贴板”。项目本身不复杂,但它解决了我日常工作里一个特别实在的痛点:KVM 切换后剪贴板内容经常丢,Windows Server 2019 远程会话里复制粘贴偶尔失效,后台更新重启之后,之前复制的内容再也…

作者头像 李华
网站建设 2026/9/8 3:07:38

OpenCode:终端里的AI编程Agent,让开发流程更高效

最近这段时间,我把OpenCode彻底用成了终端里的主力AI编程搭档。之前我也在IDE里用AI辅助写代码,但每次遇到“改完这个文件再跑一下测试”这种需求,总觉得AI和终端之间隔着一层,上下文传递得靠复制粘贴,很割裂。换到Ope…

作者头像 李华
网站建设 2026/9/8 3:06:45

演化博弈仿真代码包:从zip解压到复制者动态与Moran过程实践

简介:这是一份基于MATLAB编写的演化博弈仿真代码包,面向博弈论初学者、生物与社会经济模型研究者和MATLAB仿真爱好者。资源围绕X与Y两种策略在群体中的动态演化过程展开,通过复制动态或Fermi规则等机制模拟策略更新,并利用绘图函数…

作者头像 李华
网站建设 2026/9/8 3:06:38

协作共享数据分析平台的设计与实现

1 选题依据 随着科研不断的深入研究和大数据时代背景下,海量且结构复杂的数据成为研究生们探索医学奥秘的关键资源[1]。对于老师指导的研究生团队而言,他们在开展科研项目时,往往会面临许多问题。团队成员收集的数据分散且孤立,缺…

作者头像 李华
网站建设 2026/9/8 3:05:58

MB85RC64 FRAM驱动开发:从I2C时序到Linux内核实战

简介:这是一份面向STM32嵌入式开发者的MB85RC64铁电存储器(FRAM)驱动源码,采用C语言编写,代码分成源文件和头文件两个部分,便于模块化集成与接口调用。MB85RC64由富士通公司推出,兼具高速读写、…

作者头像 李华
网站建设 2026/9/8 3:02:37

硬件电路设计实战:从原理图到打样调试的完整闭环

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

作者头像 李华