高内聚低耦合是类职责划分的结果,需通过单一职责、接口隔离、依赖注入、策略模式及AOP等手段实现,而非仅靠命名或注释。

高内聚低耦合不是口号,是类职责划分的结果
在 Java 中,高内聚低耦合不是靠加注释或起个好名字就能实现的,它直接取决于你是否把“一个类该做什么”想清楚了。内聚性差的表现是:UserService 里既有发邮件逻辑、又有导出 Excel 的代码、还顺手调用了 PayService 做扣款——这不是功能丰富,是职责爆炸。耦合高的典型是:OrderProcessor 直接 new AlipayClient(),或者硬编码数据库连接字符串。
用接口隔离 + 依赖注入切断硬依赖
Java 中最常用且有效的解耦手段是:面向接口编程 + 构造器注入(或 setter 注入)。关键不在于用了 Spring,而在于你有没有让类只依赖抽象,而不是具体实现。
-
PaymentService接口定义pay(Order order),AlipayServiceImpl和WechatPayServiceImpl各自实现 - 业务类如
OrderService不持有new AlipayServiceImpl(),而是通过构造器接收PaymentService接口实例 - 测试时可轻松传入
MockPaymentService,无需启动支付网关 - Spring 的
@Autowired只是自动化这一步;不用框架时,手动 new + 传参同样有效
内聚提升靠单一职责 + 方法粒度控制
一个类是否高内聚,看它的所有方法是否都在为同一组核心状态服务。比如 ShoppingCart 类,它的字段应该是 items、discountCode、currency,所有方法围绕这些字段增删改查、计算总价、应用优惠——而不是在里面写 sendSms(String phone)。
- 如果发现某个方法需要大量传参(比如 5 个 String + 2 个 boolean),大概率它本不该属于当前类
- 把「校验订单」逻辑从
OrderService.placeOrder()中抽成独立的OrderValidator类,比塞一堆 if-else 更内聚 - 避免工具类大杂烩:不要有
CommonUtils,按领域拆成DateUtils、JsonUtils、StringUtils,每个只做一类事
警惕看似松耦合实则隐式耦合的陷阱
有些写法看起来解耦了,但运行时仍强绑定,比如:
立即学习“Java免费学习笔记(深入)”;
public class NotificationService {
public void notify(String type, String content) {
switch (type) {
case "email": sendEmail(content); break;
case "sms": sendSms(content); break;
default: throw new IllegalArgumentException("Unknown type: " + type);
}
}
}
这段代码虽然没 new 具体实现类,但 type 字符串值成了隐式契约——新增推送渠道必须改这个 switch,违反开闭原则。真正解耦应是:
- 定义
NotificationChannel接口 - 用工厂或策略模式根据配置加载对应实现(如
spring.profiles.active=prod决定用哪个 Bean) - 避免字符串、枚举作为行为分发依据,除非它们本身被封装在策略内部
内聚和耦合从来不是孤立指标,改一个常牵动另一个。最容易被忽略的是:日志埋点、异常处理、事务边界这些横切关注点,如果直接在业务方法里写 log.info(...) 或 transactionManager.commit(),会悄悄拉低内聚、抬高耦合——它们该由 AOP 或统一拦截器接管。










