直接拆分胖接口为小而专的接口是提升可维护性的最有效方式,依据isp原则按职责粒度拆分,如authable、runnable等,并通过组合替代全盘继承,警惕接口污染与反向依赖。

直接拆掉“万能接口”,换成几个小而专的接口,是提升可维护性的最有效方式。胖接口强迫实现类写一堆空方法、改一处牵动全局、新加功能还得协调所有使用者——这些痛点,ISP 都能治。
识别胖接口的典型信号
一个接口是不是该拆,看这几点:
- 实现类里出现大量空方法体(public void eat() { })或抛 UnsupportedOperationException
- 不同实现类只用其中 2–3 个方法,其余完全闲置
- 接口名宽泛(如 UserService、Machine),但内部混着认证、通知、日志、状态管理等不相关行为
- 某次修改(比如加个 sendSms())导致十几个无关模块编译失败或需要同步改代码
按职责粒度拆分接口
不是随便切,而是按“谁用什么”来分组。核心是让每个接口只表达一类明确能力:
- 用户操作 → 拆成 Authable(登录/登出)、ProfileUpdatable(改资料)、PasswordResettable(重置密码)
- 设备控制 → 拆成 Runnable(启动/停止)、Monitorable(获取温度/电量)、Upgradable(固件升级)
- 文档处理 → 拆成 Creatable、Editable、Exportable、Printable
拆完后,Robot 类只需实现 Runnable 和 Monitorable;手机 App 的用户模块只依赖 Authable 和 PasswordResettable —— 各取所需,互不干扰。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
用组合代替“全盘继承”
避免让一个类实现七八个接口。合理做法是:
- 业务实体类(如 User)不直接实现一堆接口,而是持有多个小服务对象(authService、profileService)
- 对外暴露的门面接口(Facade)可组合多个小接口,供高层模块统一调用,但内部仍是解耦的
- 必要时用默认方法提供通用逻辑(如 Loggable.log(String msg) 加默认实现),减少重复代码,但不因此把无关功能塞进同一接口
警惕接口污染和反向依赖
新增方法前先问:这个方法是为现有所有实现类服务的?还是只为某个新客户端加的?如果是后者,就该新建接口,而不是往老接口里硬塞:
- 已有 PaymentProcessor 接口含 pay()、refund();现在要支持分账,不要加 splitPayment(),而是定义 SplitCapable 接口
- 如果发现某个实现类总要同时实现 A 和 B 接口,说明它们本就该合并;反过来,若多数实现类只选其一,就坚决不能合
- 每次接口变更,检查所有实现类是否真受影响——没被影响的,说明接口设计已越界
不复杂但容易忽略:ISP 不是追求接口数量最多,而是让每个接口的契约清晰、稳定、可预测。拆得对,改起来才不怕踩雷。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










