多态核心是运行时动态绑定,工厂应返回接口、避免类型判断;用注册表替代if-else;通过模板方法将差异封装在钩子中;业务层不应出现具体类名或instanceof判断。

多态不是给工厂加个接口就完事,关键在于让创建逻辑彻底脱离编译期判断,把“选谁来干”这件事交给运行时决定。工厂本身要变薄、变傻、只管交付,不掺和类型判断。
让工厂返回接口,而不是具体类
原始工厂常写成 if ("json".equals(type)) return new JsonFileLoader(),这等于把类型决策锁死在代码里。正确做法是:工厂方法签名必须是 FileLoader create(String type),返回统一接口。业务代码拿到后直接调用 loader.load(),JVM 自动绑定到实际子类——此时连 JsonFileLoader 这个类名都不该在业务层出现。
用注册表替代 if-else 分支
把“字符串 → 加载器实现”的映射从代码搬到启动时的注册过程:
- 定义
Map<string supplier>> registry</string> - 扫描所有
@Supports("xml")注解的实现类,自动注册进 map - 工厂的
create()方法只做查表:registry.get(type).get()
新增一种格式?加一个实现类 + 注解即可,工厂源码一行不用改。
用模板方法封装流程共性,把多态落在钩子上
不同格式加载差异集中在打开、解析、关闭三步,主流程完全一致。可抽象为:
-
final Object load(String path)—— 模板方法,固定顺序 abstract InputStream open(String path)abstract Object parse(InputStream in)abstract void close(InputStream in)
每个子类只专注自己那块逻辑,多态真正作用在三个抽象方法上,工厂只负责交出正确的子类实例。
警惕多态没走通的信号
如果业务代码里出现这些,说明解耦失败:
- 用
instanceof判断类型再转型 - 调用前先
if (loader instanceof JsonFileLoader) - 工厂被
new在 service 里,或没通过构造器注入
真正的多态落地,是业务层完全感知不到背后是谁在干活。











