My App

工厂方法

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() —— 根据类型创建不同的组件元素

On this page