高内聚指类内部职责单一、专注同一变化原因,低耦合指类间依赖抽象接口而非具体实现;二者体现为清晰命名、构造注入、接口隔离与职责明确。

“高内聚、低耦合”不是抽象口号,而是判断一个类是否健康、一个系统是否容易维护的实用标尺。它不靠感觉,而体现在代码怎么写、依赖怎么传、职责怎么分上。
高内聚:一个类只对一种变化负责
内聚讲的是类内部的“专注度”。如果一个类同时做用户登录、发邮件、导出报表、记录日志,那它就不是高内聚——这些事变化原因完全不同:登录策略改了要动它,邮件模板换了要动它,报表格式变了还要动它。一次改动牵出三处风险。
- 用一句话能说清它的核心作用,比如“校验订单金额与库存是否匹配”,而不是“处理订单相关各种事情”
- 类里所有方法操作的都是同一组状态,且因同一个业务原因被修改
- 避免出现 if (type == "email") 或 switch (format) 这类混装多种行为的分支逻辑
- 拒绝模糊命名:UserHelper、DataUtil、Manager 这类名字往往意味着职责已失控,换成 OrderValidator、PasswordHasher 更准确
低耦合:依赖只认接口,不认实现
耦合讲的是类之间的“粘连度”。当一个类直接 new 一个 JdbcTemplate、静态调用某个工具方法、或在 Controller 里硬编码 ObjectMapper 实例,它就和具体技术细节焊死了。这种代码一换数据库、一换 HTTP 客户端,就得四处改。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 所有外部依赖(数据库、缓存、HTTP 调用)必须通过构造函数注入,类型是接口(如 UserRepository、HttpClient)
- 禁止跨层持有底层对象:Service 层不该知道 RedisTemplate,只该依赖 CacheService.get(key)
- 测试时能直接传入 new MockUserRepository() 并跑通单元测试,就是低耦合的明确信号
- 不要 import com.xxx.service.impl.XxxServiceImpl,只允许 import com.xxx.service.XxxService
它们不是目标,而是职责清晰后的自然结果
刻意追求“高内聚低耦合”容易流于形式。真正关键的是想清楚:这个类为谁服务?解决什么问题?哪天需求变了,它会因为什么原因被修改?
立即学习“Java免费学习笔记(深入)”;
- 一个类被 Controller、定时任务、消息监听器各调用不同方法,说明它实际承担多个角色,该拆了
- User 类里有 encryptPassword() 方法,这不属于用户本身的领域行为,应移入 PasswordEncoder
- DTO + 工具类组合看似解耦,实则割裂数据与行为,user.isValidEmail() 比 UserHelper.isValidEmail(user.getEmail()) 更内聚
- 继承不是首选,组合+接口才是控制依赖边界的更安全方式
不复杂但容易忽略。

















