避免继承滥用导致的耦合,核心是用接口定义行为契约、依赖注入替代new、抽象基类仅作技术支撑;如日志用eventlogger接口而非含字段的抽象类,业务类只持接口引用,通过构造器注入或spring管理实现替换。

避免继承滥用导致的耦合,核心不是少用继承,而是让“谁依赖谁”更清晰、更可控。关键在于把编译期强绑定的关系,换成运行期可插拔的契约协作。
用接口定义能力,而不是用父类塞实现
接口只声明“能做什么”,不带字段、不写构造器、不暴露 protected 成员。比如日志功能,定义 EventLogger 接口,仅含 log(String event);别用抽象类预置 filePath 或 bufferSize——这些是实现细节,污染契约。
- 按使用场景拆分接口:前台只需 SeatReservation,后台调度用 SeatLockManager,不堆砌 CommonService
- 每个实现类完全自治:FileLogger 和 SlackLogger 互不感知,也不共享基类里的格式化逻辑
- 业务类字段和构造参数都声明为接口类型,不写 new 具体类
把 new 拆掉,把创建权交给外部
业务类里写 new UserServiceImpl(),等于同时绑定了实现类、构造方式、生命周期。换数据库、加缓存、写单元测试都得改源码。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 构造器注入:业务类通过构造函数接收接口实例,由 Spring 或工厂传入
- Spring 管理时用 @Autowired 注入接口,替换实现不改一行业务代码
- 手动管理可用 DataFactory.createUserService(),避免硬编码类名
继承只用于稳定骨架,且必须设防
若多个子类确有共用流程(如 HTTP 客户端统一处理重试、超时、Header 注入),可设计抽象基类,但要满足:
- 该基类不被外部直接依赖,也不实现任何业务接口
- 所有 public 方法标记为 final,只留少量 protected 钩子供定制
- 它只是技术支撑层,真正的行为契约仍由上层接口承担
优先组合,尤其对通用能力
日志、缓存、校验、权限这些不是“是一种”,而是“用到什么”。与其让业务类继承 CachedService,不如让它持有一个 CacheProvider 实例。
- CachedDao 内部持有 private final Dao delegate,需要时委托调用
- 缓存逻辑隔离,不污染数据访问契约
- 测试时可直接注入 mockDao,不用构造整棵继承树
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










