接口隔离原则要求客户端只依赖所需接口,需拆分臃肿接口以聚焦单一行为;识别信号包括方法使用率低、强制抛异常、修改影响无关模块等;应按业务角色或场景拆分,如orderquery/creation/cancellation,并用组合替代继承,辅以契约测试保障质量。

接口隔离原则(ISP)的核心是:客户端不应依赖它不需要的接口。当一个接口承担了过多职责,变得臃肿时,修改它会影响多个不相关的模块,增加耦合,降低可维护性与可测试性。拆分臃肿接口,本质是让每个接口只聚焦一类行为,从而提升系统灵活性和演化能力。
识别臃肿接口的典型信号
以下情况往往意味着接口已违背ISP:
- 接口中包含大量方法,但不同调用方只使用其中一小部分
- 实现类被迫抛出 UnsupportedOperationException 或返回 null/空集合来应对未支持的方法
- 新增一个功能需要修改已有接口,导致大量无关实现类被迫调整
- 单元测试中频繁使用 mock 并跳过大部分方法,只验证少数几个
按业务角色或使用场景拆分接口
不要按技术层次(如“DAO”“Service”)粗粒度划分,而应围绕“谁在什么场景下需要什么能力”来建模:
- 例如订单服务接口,可拆为 OrderQuery(提供查询、分页、状态统计)、OrderCreation(仅含创建、校验逻辑)、OrderCancellation(专注取消流程及补偿)
- 同一实体的不同操作权限也可分离:如 ReadOnlyUser 和 AdminUser,避免普通用户实现删除或批量更新方法
- 客户端驱动拆分更可靠——先看前端页面、定时任务、第三方回调各自调用了哪些方法,再反向定义接口
利用组合代替继承,避免接口爆炸
拆分后接口数量可能上升,需防止过度碎片化:
- 优先复用已有小接口组合成新契约,例如 PaymentProcessor 可继承 Chargeable + Refundable,而非定义一个大接口
- 对高度内聚的操作组保留聚合接口(如 InventoryManager),但确保其所有方法被同一类调用方高频共用
- 在 Spring 等框架中,可通过 @Qualifier 或接口分组注解控制注入粒度,避免 Bean 查找混乱
配合契约测试保障拆分质量
拆分不是重构终点,需验证各子接口仍满足原有语义约束:
- 为每个小接口编写独立的契约测试(Contract Test),覆盖其声明的行为边界与异常场景
- 检查实现类是否仍符合 Liskov 替换原则——替换为任一子接口的实现后,调用方逻辑不变
- 在 CI 中运行接口兼容性检查,例如使用 OpenAPI Diff 或 Pact,确保下游消费者不受意外变更影响
接口不是越小越好,而是要让每个接口表达清晰的角色契约。拆得合理,系统才真正具备按需演进的能力。









