简单工厂不是gof 23种设计模式之一,其核心是将对象创建逻辑集中到一个工厂类中,通过静态方法+条件判断返回具体子类实例,但因硬编码类名、违反开闭原则、运行时类型错误等导致无法彻底解耦。

简单工厂本身不是 GoF 23 种设计模式之一,而是一种编程习惯或“工厂雏形”,它的核心目标是把 对象的创建逻辑集中到一个类中,从而让客户端代码不直接使用 new 关键字实例化具体类。这在一定程度上实现了“创建与使用分离”,但解耦程度有限——它只是把 new 的位置从调用方挪到了工厂类里,并没有真正消除对具体类型的依赖。
为什么简单工厂不能彻底解耦?
简单工厂通常通过一个静态方法 + if/else 或 switch 判断类型来返回不同子类实例。例如:
public class AnimalFactory {
public static Animal createAnimal(String type) {
if ("dog".equals(type)) {
return new Dog(); // 仍直接依赖 Dog 类
} else if ("cat".equals(type)) {
return new Cat(); // 仍直接依赖 Cat 类
}
throw new IllegalArgumentException();
}
}
问题在于:工厂类本身依然 硬编码了所有具体类名,新增 Animal 子类时必须修改工厂源码(违反开闭原则),客户端虽不写 new,但传入的字符串 type 仍是隐式依赖,编译期无法检查,运行时才暴露错误。
怎样让它更松耦合?(实用改进方向)
如果坚持用简单工厂风格,可通过以下方式缓解耦合:
- 用 Class 对象代替字符串参数:把类型信息从字符串升级为 Class,让调用方传入 Class extends Animal>,工厂用反射创建实例(需确保有无参构造)。这样编译期能校验类型合法性,工厂也不再硬写 if/else。
-
配合配置文件或注解自动注册:启动时扫描带有 @Component 或自定义注解(如 @AnimalType("dog"))的类,存入 Map
。工厂查表+反射创建,新增类型只需加类+注解,无需改工厂代码。 - 退一步用工厂方法模式:把创建逻辑上移到抽象父类或接口中,由子类决定实例化谁。此时客户端只依赖抽象工厂接口,完全不感知具体实现类——这才是真正的解耦起点。
什么时候适合用简单工厂?
它适合小项目、工具类、原型验证或内部组件封装等场景,比如:
- 统一创建 JSON 解析器(Jackson/Gson)、日志器(Log4j/SLF4J)的适配封装;
- 测试中快速生成模拟对象(MockObjectFactory);
- 框架插件体系中,根据配置加载固定几种子插件(插件数量稳定、不频繁扩展)。
只要不追求高可扩展性、不常增删类型,简单工厂简洁有效;一旦业务变复杂,就该自然演进到工厂方法或抽象工厂。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











