工厂方法
Factory Method — 定义创建对象的接口,让子类决定实例化哪个类
一句话理解
不直接 new 对象,而是通过一个工厂方法来创建,让创建逻辑和使用逻辑分离。
解决什么问题
当代码中直接写死 new ConcreteClass() 时:
- 每次需要换一个实现类,就要改调用方代码
- 违反开闭原则(对扩展开放,对修改关闭)
- 创建逻辑和业务逻辑耦合在一起
怎么写
简单工厂(入门版,不属于 GoF 23 种)
用一个静态方法根据参数决定创建哪个对象:
public class AnimalFactory {
public static Animal create(String type) {
return switch (type) {
case "dog" -> new Dog();
case "cat" -> new Cat();
default -> throw new IllegalArgumentException("未知动物: " + type);
};
}
}
// 使用
Animal a = AnimalFactory.create("dog");
a.speak(); // 汪汪汪优点:调用方不再关心具体类名。 缺点:每次新增类型都要改工厂方法,还是违反开闭原则。
工厂方法模式(GoF 标准版)
把"创建哪个对象"的决定权交给子类:
// 抽象产品
public interface Animal {
void speak();
}
// 具体产品
public class Dog implements Animal {
public void speak() { System.out.println("汪汪汪"); }
}
public class Cat implements Animal {
public void speak() { System.out.println("喵喵喵"); }
}
// 抽象工厂
public interface AnimalFactory {
Animal create();
}
// 具体工厂 —— 每种产品对应一个工厂
public class DogFactory implements AnimalFactory {
public Animal create() { return new Dog(); }
}
public class CatFactory implements AnimalFactory {
public Animal create() { return new Cat(); }
}// 使用:想换产品,只需要换工厂,调用方代码不变
AnimalFactory factory = new DogFactory();
Animal a = factory.create();
a.speak(); // 汪汪汪新增一种动物时,只需要新增一个产品类 + 一个工厂类,不用改任何已有代码。
前端中的工厂
// 根据类型创建不同的表单校验器
function createValidator(type: string) {
switch (type) {
case 'email': return new EmailValidator()
case 'phone': return new PhoneValidator()
default: throw new Error(`未知校验器: ${type}`)
}
}使用场景
- Spring 的
BeanFactory—— 根据配置/注解决定创建哪个 Bean - SLF4J 的
LoggerFactory.getLogger()—— 底层可以是 Logback、Log4j 等 - JDBC 的
DriverManager.getConnection()—— 根据 URL 选择数据库驱动 - React 的
createElement()—— 根据类型创建不同的组件元素