高内聚低耦合的核心是用接口划清责任边界、约束协作方式、隔离变化源头;接口应聚焦业务契约、命名语义化、方法精简、依赖面向接口注入、策略化多变逻辑、包结构与接口协同演进。

用Java接口实现高内聚低耦合,核心不是“多定义几个接口”,而是用接口划清责任边界、约束协作方式、隔离变化源头。关键在设计意图是否清晰,而非接口数量多少。
接口要定义“做什么”,而不是“怎么做”
一个接口应只表达一类明确的契约,比如 OrderRepository 只管数据存取(save、findById、delete),不掺杂校验、日志或缓存逻辑;NotificationService 只承诺“发通知”,不管它是邮件、短信还是站内信。一旦接口方法里出现 if (type.equals("sms")) 或 throws RedisConnectionException,说明它已经越界了。
- 接口名用业务语义命名(如 PaymentProcessor),避免 Utils、Helper、Manager 等模糊后缀
- 方法签名聚焦输入输出,不暴露实现细节(不返回 List<HashMap>,而用 OrderSummaryDTO)
- 一个接口原则上不超过 5 个方法;若持续增长,说明职责在膨胀,该拆分
依赖必须面向接口注入,且仅限必要能力
业务类(如 OrderService)只能持有接口类型字段,且该接口必须是它真正需要协作的对象。它不需要知道数据库用 MySQL 还是 PostgreSQL,也不需要知道支付调用走的是 HTTP 还是本地 SDK。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 用构造器注入(@RequiredArgsConstructor + private final)确保依赖不可变、不为空
- 禁止在类内部 new 接口实现类,也禁止通过 Class.forName() 或 ServiceLoader 动态加载(除非是插件化场景)
- Controller 层只依赖 Service 接口,Service 层只依赖 Repository/Client/Validator 接口,绝不跨层持有(如 Service 不持 JdbcTemplate)
把多变逻辑抽成策略接口,运行时组合
当业务中存在“同一动作有多种实现”的情况(如不同渠道发券、不同规则计算运费),不要用 if-else 或 switch 分支硬编码,而应抽象为策略接口。
立即学习“Java免费学习笔记(深入)”;
- 定义 CouponStrategy 接口,含 apply(Order order) 方法
- 实现类:NewUserCouponStrategy、HolidayCouponStrategy、VipCouponStrategy
- OrderService 持有 CouponStrategy 接口,并通过 Spring 的 @Qualifier 或工厂方法选择具体实现
- 新增一种发券规则,只需加一个实现类+配置,原代码零修改
包结构与接口共演进,体现模块真实边界
接口不能孤立存在。它的位置、所属包、被谁实现、被谁使用,共同构成系统的真实模块划分。
- 按业务域建包(如 cn.edu.demo.order、cn.edu.demo.payment),接口与其实现类放在同一域包下,或分置 domain/api 和 domain/impl
- 避免跨域引用:payment 包下的接口,不应被 user 包里的类直接 new 实现类;必须通过上层 service 或门面(Facade)协调
- 公共接口(如 IdGenerator、RetryPolicy)放入 common.contract 或 infrastructure 包,但只包含稳定、无业务语义的通用能力

















