控制继承深度在两层以内最有效;超三层易致职责模糊、维护成本上升;应以组合替代中间层继承,抽功能为接口并委托调用;基类只保留稳定契约,核心方法设为final,参数通过构造器或Builder注入;字段私有化,提供受控protected方法;团队规范要求具体类标记final,用SonarQube等工具检查并CI拦截;对深层链定期重构,识别唯一子类、绕过重写、雷同子类、共享工具方法等信号及时优化。

控制继承深度在两层以内是最直接有效的做法。超过三层,类之间职责就容易模糊,改一处可能牵动多个子类,理解成本和测试负担都会明显上升。
用组合代替中间层继承
当发现某层类(比如 CachedService、ValidatedService)只是给多个子类“打补丁”,它实际承担的是能力装配职责,而不是语义上的“是一种”,那就该替换成组合。
- 把功能抽成接口,如 Cacheable、ValidationRule
- 在业务类中声明字段,如 private final Cacheable cache;
- 构造器注入具体实现,避免 new 硬编码
- 原逻辑调用改为委托,如 cache.get(key),而非 super.cache()
基类只保留稳定契约
父类不该塞进可变细节——默认超时、固定日志格式、特定异常包装方式等,这些一旦写死,子类只能覆盖或绕行,破坏封装。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 核心方法尽量声明为 final,只留少数 protected abstract 钩子
- 所有可变参数(重试次数、序列化方式、日志级别)必须通过构造器或 Builder 注入
- 避免在父类构造器中调用可被重写的方法,防止 NullPointerException
- 字段全设为 private,需扩展时提供受控的 protected 方法,不暴露字段
从结构上限制继承蔓延
不是靠人盯,而是靠规则和工具把住关口。
立即学习“Java免费学习笔记(深入)”;
- 团队规范明确:所有具体实现类标记为 final,禁止被继承
- 用 SonarQube 或 IDEA 的 Inheritance depth 检查,超两层标黄提示
- CI 阶段拦截继承深度超标代码,不让它合入主干
- 对已有深层链(如 Vehicle → Car → Sedan → ElectricSedan),先识别中间层是否只是分类标签,而非承载复用逻辑
定期识别重构信号
别等出问题才动手,日常开发中留意这些苗头:
- 某个抽象类只有唯一子类 → 很可能过度设计,考虑移除或转为具体类
- 子类大量重写父类方法只为“绕过逻辑” → 那部分逻辑本该抽成可插拔组件
- 多个子类雷同,仅字段不同 → 建模维度错位,应改用配置 + 组合
- “查找所有子类”结果里,多个子类共享的只是几个工具方法 → 抽成工具类或默认方法接口更合适

















