高内聚低耦合是日常编码中的具体取舍:类应职责单一(如PriceCalculator只算价)、依赖抽象而非实现(用PaymentGateway接口而非new具体类)、优先组合(OrderService持有Validator)而非继承,且须从第一行代码就践行。

高内聚低耦合不是口号,而是每天写Java时你必须做的一系列具体取舍。它直接决定你改一行代码会不会牵出三个bug、加个新支付方式要不要动订单核心逻辑、两个人同时改同一模块会不会天天merge冲突。
怎么一眼识别“低内聚”?看类里有没有 calculatePrice、sendEmail、logToDB 全挤在一个类里
比如一个 BookManager 类里既算折扣、又发短信、又更新库存——这不是“功能丰富”,是职责污染。这类代码的典型症状是:方法越写越多,if-else 越嵌越深,改个价格策略得翻遍整个类找所有相关逻辑。
- 真正高内聚的做法:把价格计算抽成
PriceCalculator,通知抽成NotificationService,库存抽成InventoryManager - 每个类只暴露 1~3 个 public 方法,其余全是 private 辅助逻辑
- 如果一个类的测试用例要 mock 支付、邮件、缓存、日志四个对象,那它大概率已经低内聚了
为什么 new PayPalGateway() 是耦合陷阱?而 PaymentGateway gateway 不是
硬编码 new 某个实现类,等于把业务逻辑和具体技术绑定死。今天用支付宝,明天切 Stripe,就得全局搜 new PayPalGateway 替换——漏一处就线上报错。
- 正确姿势:定义接口
PaymentGateway,让业务类只依赖这个抽象 - 用构造器注入(
public PaymentService(PaymentGateway gateway))或 Spring 的@Autowired,把实例创建交给容器 - 新增支付方式?加个
WechatPayGateway实现类 + 配置切换,0 行原有业务代码改动
组合优于继承,不是教条——是避免 super.doSomething() 变成定时炸弹
继承看起来省事,但一旦父类方法行为变化(比如加了日志、改了校验顺序),所有子类都可能静默失效。更糟的是,子类被迫知道父类内部细节才能重写。
立即学习“Java免费学习笔记(深入)”;
- 换成组合:
OrderService持有private final Validator validator和private final Auditor auditor - 每个组件可独立替换、单独测试、版本升级互不影响
- 想给某个订单流程加风控?换个
RiskValidator注入进去就行,不用动继承链
最容易被忽略的点是:高内聚低耦合不是写完再“重构”出来的,而是在第一次写 if 分支、第一次加 new、第一次让两个不相关的功能共享一个类时,就该按住暂停键问自己一句——这事,真该归它管吗?









