多态是打破硬编码工厂的核心机制,需满足工厂返回抽象类型、客户端调用抽象接口、jvm运行时动态绑定三者缺一不可;通过接口统一加载器、注册表替代if-else、模板方法封装流程差异,实现开闭原则与真正可插拔。
多态是打碎硬编码工厂的核心杠杆,不是装饰,而是执行机制。关键不在于“有没有接口”,而在于“调用时是否真由运行时决定行为”。
用多态让工厂真正可插拔
硬编码工厂(比如 if (type.equals("json")) return new JsonFileLoader())的问题是:分支逻辑写死在代码里,新增格式就得改工厂类,违反开闭原则。多态的解法是把“创建权”交给子类或配置,让类型选择脱离编译期绑定。
- 工厂返回类型必须是抽象的(如
FileLoader接口),不能是JsonFileLoader这样的具体类 - 所有加载器实现统一接口,各自覆盖
load(String path)方法,内部处理格式特异性逻辑 - 客户端只声明
FileLoader loader = factory.create(type),后续调用loader.load(...)时,JVM 自动路由到实际类,业务层完全无感知
把类型映射从代码搬到配置或注册表
避免在工厂里写一堆 if-else 或 switch。换成注册驱动方式:
- 启动时扫描所有
FileLoader实现类,按约定规则(如类名后缀、注解@Supports("xml"))自动注册到Map<string supplier>></string> -
create(String type)方法只做查表:registry.get(type).get() - 新增一种格式,只需加一个实现类 + 注解,无需动工厂源码
配合策略模式封装加载流程差异
不同文件格式初始化行为不同(如 JSON 需解析为 Map,CSV 需按行切分),但主流程一致:打开 → 读取 → 解析 → 关闭。可定义模板方法:
abstract class FileLoader {
final Object load(String path) {
InputStream in = open(path);
Object data = parse(in); // 多态:子类实现
close(in);
return data;
}
abstract InputStream open(String path);
abstract Object parse(InputStream in);
abstract void close(InputStream in);
}
此时多态作用在三个钩子方法上,每个格式专注自己那一块,工厂只管交付正确的子类实例。
警惕解耦失败的信号
- 业务代码里出现
instanceof JsonFileLoader或强制转型 → 多态没走通 - 工厂类被
new在 Service 里,而不是通过构造器注入或 Spring@Autowired→ 创建逻辑仍泄漏 - 配置传的是类全限定名(如
"com.xxx.JsonFileLoader")→ 编译期强耦合,应传语义标识(如"json")
本质上,多态不是写完接口就自动生效的魔法,它需要工厂返回抽象、客户端调用抽象、JVM 在运行时完成动态绑定——三者缺一不可。











