接口隔离原则(ISP)要求每个接口仅暴露调用方真正需要的方法,避免 UnsupportedOperationException、null 返回或空方法体;识别臃肿接口的信号包括:实现类超1/3方法抛异常、多服务共用但调用方法几乎无重叠、“Method is never used”警告超40%、单元测试需stub十余方法仅验2–3个。
接口隔离原则(isp)不是为了“多建几个接口”,而是让每个接口只暴露调用方真正需要的方法,从而消除实现类中大量 throw new unsupportedoperationexception()、return null 或空方法体这类变量冗余和逻辑污染。
识别臃肿接口的典型信号
不用等系统上线后出问题,开发阶段就能看出苗头:
- 某个接口的实现类里,超过三分之一的方法只是抛异常或返回默认值
- 同一个接口被订单服务、报表服务、通知服务共用,但三者调用的方法集合几乎不重叠
- IDE 显示 “Method is never used” 的警告集中在某几个方法上,且比例持续高于40%
- 写单元测试时,mock 对象要 stub 十几个方法,但实际只验证其中 2–3 个
按角色/场景拆分接口,而不是按实体
别再写 UserOperationService 这种包揽增删改查+导出+权限校验的大接口。重点看“谁在用、怎么用”:
- 前端页面需要:查询用户列表、根据ID查详情 → 提供
UserQueryService - 后台任务需要:批量禁用、导出Excel → 提供
UserBatchService - 权限模块需要:检查用户是否拥有某角色 → 提供
UserPermissionChecker - 各接口之间无继承关系,也不强求统一前缀,职责清晰比命名工整更重要
用组合替代“万能实现类”
避免出现一个类实现七八个接口,最后变成“瑞士军刀式Bean”。更自然的做法是:
- 把通用能力下沉为独立组件,比如
PasswordEncoder、IdGenerator - 业务类只持有所需组件的引用,通过组合获得能力,而不是靠实现一堆接口来“声明身份”
- 例如:订单创建服务只需依赖
InventoryClient和PaymentGateway,不必实现NotificationCapable或Loggable接口
渐进式迁移,保障兼容性
老系统不能推倒重来。推荐分三步走:
- 先定义新接口,标注
@Deprecated原接口中即将废弃的方法 - 新功能全部对接新接口;旧功能逐步切流,同时保留旧接口代理层(转发到新实现)
- 确认所有调用方迁移完成,再删除旧接口——这一步必须有全链路日志兜底,不能只靠代码搜索

















