工厂方法返回null或ClassCastException的主因是子类未正确重写createProduct()或返回类型不符;应使用泛型返回、安全转换、严格契约验证及类型测试。

工厂方法为什么总返回 null 或 ClassCastException
常见原因是子类工厂没正确重写 createProduct(),或返回了错误类型。比如抽象工厂接口声明返回 Product,但具体工厂返回了 LegacyProduct,而调用方强转成 ModernProduct —— 运行时就抛 ClassCastException。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 在抽象工厂中把返回类型设为泛型:
,配合T createProduct(Class type) type.cast(...)做安全转换 - 所有具体工厂必须确保返回实例满足接口契约,别绕过编译检查写
return (ModernProduct) new LegacyProduct() - 单元测试里对每个工厂显式验证返回值的
instanceof类型,不只测是否非空
SimpleFactory 和 FactoryMethod 混用导致扩展困难
很多人一开始用静态 SimpleFactory.create(String type),后来加新类型就往里塞 if ("v2".equals(type)) 分支——这违反开闭原则,也难做 Spring Bean 管理。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 从项目初期就用
FactoryMethod:让每个产品族有独立工厂类(如PaymentFactory、NotificationFactory),通过 Spring 的@Qualifier注入具体实现 - 避免在工厂内部硬编码判断逻辑;改用配置驱动:读取
application.properties中的payment.strategy=alipay,再查Map容器获取实例 - 如果真需要简单工厂,至少把它变成非静态、可被继承的类,并预留
protected钩子方法供子类定制创建逻辑
抽象工厂中产品族耦合引发测试失败
当 AbstractFactory 同时创建 Button 和 Checkbox,但测试时只 mock 其中一个,另一个却依赖真实实现——结果 UI 组件初始化失败,或出现 NPE。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 抽象工厂的每个创建方法应彼此独立,不要在
createButton()里调用createCheckbox();否则破坏单一职责,也增加测试隔离难度 - 使用构造注入替代工厂内直接 new:把
ButtonFactory和CheckboxFactory作为参数传入抽象工厂构造器,方便单元测试替换 - 考虑用 Builder 模式收口复杂对象创建,把工厂退化为“策略选择器”,例如
UiComponentBuilder.forTheme("dark").withButtonStyle("rounded")
public interface ProductFactory工厂模式真正的难点不在结构图,而在边界控制——什么时候该让工厂知道“怎么造”,什么时候只让它决定“造哪个”。漏掉这个分寸,再多的{ T create(Class clazz); } public class JsonProductFactory implements ProductFactory { @Override public JsonProduct create(Class clazz) { return clazz.cast(new JsonProduct()); // 安全转型 } }
abstract 和 interface 都会变成套娃式维护负担。










