Skip to content

工厂方法模式

一、产生背景(简单工厂的缺陷)

简单工厂所有创建逻辑写在同一个工厂类,新增产品必须修改工厂代码,违背开闭原则。 工厂方法将工厂抽象化,每种产品对应独立工厂,新增产品只新增产品类+对应工厂,不修改原有代码,完全符合开闭原则。

二、四大核心角色

  1. 抽象工厂 AbstractFactory(CoffeeFactory接口) 定义创建产品的标准工厂方法 createCoffee(),所有具体工厂必须实现该方法。
  2. 具体工厂 ConcreteFactory 一对一绑定产品,只负责创建对应产品: AmericanCoffeeFactory 生产美式、LatteCoffeeFactory 生产拿铁。
  3. 抽象产品 Product(Coffee抽象类) 定义产品统一行为规范,getName()addMilk()addSugar()
  4. 具体产品 ConcreteProduct 实现抽象产品,如AmericanCoffeeLatteCoffee,由对应专属工厂创建。

三、UML调用流程

  1. CoffeeStore(业务调用方)依赖抽象工厂CoffeeFactory
  2. 业务传入具体工厂实现类;
  3. 调用工厂createCoffee()生成对应咖啡实例;
  4. 新增摩卡咖啡:仅新增MochaCoffee产品 + MochaCoffeeFactory工厂,原有代码无改动。

四、咖啡案例代码实现

1. 抽象产品 Coffee

java
public abstract class Coffee {
    public abstract String getName();
    public void addMilk(){}
    public void addSugar(){}
}

2. 具体产品

java
// 美式咖啡
public class AmericanCoffee extends Coffee{
    @Override
    public String getName() {
        return "美式咖啡";
    }
}
// 拿铁咖啡
public class LatteCoffee extends Coffee{
    @Override
    public String getName() {
        return "拿铁咖啡";
    }
}

3. 抽象工厂 CoffeeFactory

java
public interface CoffeeFactory {
    Coffee createCoffee();
}

4. 具体工厂

java
// 美式工厂
public class AmericanCoffeeFactory implements CoffeeFactory{
    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }
}
// 拿铁工厂
public class LatteCoffeeFactory implements CoffeeFactory{
    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }
}

5. 业务门店 CoffeeStore

java
public class CoffeeStore {
    private CoffeeFactory factory;
    // 注入具体工厂
    public CoffeeStore(CoffeeFactory factory){
        this.factory = factory;
    }
    public Coffee orderCoffee(){
        Coffee coffee = factory.createCoffee();
        coffee.addMilk();
        coffee.addSugar();
        return coffee;
    }
}

6. 客户端调用

java
// 点美式
CoffeeStore store = new CoffeeStore(new AmericanCoffeeFactory());
Coffee coffee = store.orderCoffee();
// 点拿铁
CoffeeStore store2 = new CoffeeStore(new LatteCoffeeFactory());
Coffee latte = store2.orderCoffee();

五、优缺点

优点

  1. 完全符合开闭原则:新增产品只新增产品、工厂类,原有代码无需修改;
  2. 单一职责:每个工厂只生产一种产品,创建逻辑分散,故障隔离;
  3. 调用方只依赖抽象工厂、抽象产品,与具体实现解耦。

缺点

  1. 类爆炸:每新增一款产品,必须同步新增1个产品类 + 1个工厂类,项目类文件成倍增加,提升系统复杂度;
  2. 代码层级变多,阅读与维护成本上升

六、简单工厂 vs 工厂方法

  1. 简单工厂:单工厂类承载所有创建逻辑,新增产品要改工厂代码,违反开闭;
  2. 工厂方法:工厂抽象分层,产品与工厂一一对应,新增产品不修改旧代码,满足开闭。

七、面试简答

问:工厂方法模式角色、优缺点,和简单工厂区别? 答:

  1. 四大角色:抽象工厂、具体工厂、抽象产品、具体产品;产品与具体工厂一一对应;
  2. 优点:满足开闭原则,新增产品无需修改原有代码,职责单一、解耦;
  3. 缺点:新增产品会同时新增产品类和工厂类,类数量急剧膨胀;
  4. 对比简单工厂:简单工厂只有一个工厂类,扩展需修改工厂代码;工厂方法拆分多个独立工厂,符合开闭原则。

Powered by VitePress 1.6.4 | 持续更新中