多态接口设计须遵循接口隔离原则(ISP),即按角色和行为职责拆分接口、面向调用方视角定义、避免强制实现无意义方法,并合理使用默认方法辅助演进。

多态接口设计要遵循接口隔离原则(ISP),关键不是堆功能,而是按角色分接口、按需暴露方法。一个接口只表达一种能力,客户端只依赖它真正用到的那个接口,不被无关方法干扰。
按行为职责拆分接口
把大而全的接口打散成多个小接口,每个只定义一类相关行为。比如动物系统里,别写一个IAnimalAction包含eat()、fly()、swim()——狗实现时得空着fly(),鸟又不需要swim()。
- 定义
Flyable接口,只含fly() - 定义
Swimmable接口,只含swim() - 定义
Runnable接口,只含run()
这样Bird类可以只实现Flyable和Runnable,Fish只实现Swimmable,各取所需,无冗余实现。
面向调用方视角定义接口
同一个业务实体,对不同使用者暴露不同接口。比如订单服务:
立即学习“Java免费学习笔记(深入)”;
- 面向普通用户:只提供
OrderQuery接口(含getOrderById()) - 面向外部系统:提供
OrderCreation接口(含createOrder()) - 面向后台管理:提供
OrderAdmin接口(含增删改查全部方法)
而不是让所有调用方都依赖一个囊括全部操作的FullOrderService接口。这样修改后台功能时,不会意外影响前端查询逻辑。
避免强制实现无意义方法
当某个实现类明显不该有某项能力时,说明接口混入了不该有的职责。典型反例是IWorker接口同时定义work()和eat()——机器人能work(),但eat()毫无意义,强行实现就是违反ISP。
- 应拆为
Worker(含work())和LivingBeing(含eat()) - 人类类可同时实现两个接口,机器人只实现
Worker - 安全门场景同理:防盗、防火、防水应为三个独立接口,学校门全实现,家庭门只选防盗+防火
合理使用默认方法辅助演进
Java 8+ 的默认方法可用于平滑升级,但不能用来“偷懒”塞进非核心能力。例如日志接口:
-
ILogger定义基础log(String msg) -
IErrorLogger扩展logError(Throwable t),并提供默认空实现(不强制子类处理) - 只有真正需要错误日志能力的组件才去实现或调用该方法
重点是:默认方法是补丁,不是替代职责拆分的借口。接口主体仍须保持精简、聚焦。


















