接口隔离原则要求按行为职责拆分小接口,面向调用方定义精准契约,并用default方法平滑演进,最终实现物理层契约隔离。

在 Java 接口中遵循接口隔离原则(ISP),核心是让每个接口只表达一种明确的能力或角色,不强塞无关方法。不是“少写几个方法”就行,而是从调用方视角出发,把抽象契约切得准、分得清、用得稳。
按行为职责拆小接口,不堆功能
一个接口只定义一类紧密相关的行为,避免出现“全能但无用”的大接口。比如动物系统里,别定义 IAnimal 包含 fly()、swim()、run() 全部方法——狗实现时得空实现 fly(),鸟又得忽略 swim()。
- 定义
Flyable:只含fly() - 定义
Swimmable:只含swim() - 定义
Runnable:只含run()
这样 Bird 类可同时实现 Flyable 和 Runnable,Fish 只实现 Swimmable,各取所需,没有冗余实现负担。
面向调用方定义契约,不搞一接口通吃
同一个业务实体,对不同使用者暴露不同接口。契约不是越全越好,而是越贴越准。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 面向 App 用户:只提供
OrderQuery(含getOrderById()) - 面向支付网关:只提供
OrderPayment(含pay()、cancel()) - 面向后台运营:提供
OrderAdmin(含增删改查及导出)
这样订单服务升级退款逻辑时,App 查询模块完全不受影响,也不用重新编译。
用默认方法辅助演进,不破坏已有实现
接口需要扩展时,优先用 default 方法提供兼容性支持,而不是直接加抽象方法逼所有实现类改代码。
- 新增日志能力?加
default void logAction(String action) { /* 空实现或基础打点 */ } - 后续子类按需重写,老实现类无需改动即可编译通过
- 注意:default 方法不能替代职责拆分,它只是演进缓冲,不是偷懒理由
物理层隔离契约,不止于代码 interface
企业级开发中,接口隔离要落到契约文件、SDK 和部署层面,才算真正落地。
- OpenAPI 按角色拆成多个 YAML 文件:如
app-user-api.yaml、admin-user-api.yaml - 共用 DTO 抽到独立
shared-models.yaml,用$ref引入,避免字段不一致 - Dubbo 服务按场景定义多个 interface:如
UserReadService和UserAdminService,不共用一个UserService - Spring Boot 中用
@Profile控制不同契约对应的 Controller 是否加载,而非靠运行时权限注解过滤
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










