工厂模式(简单工厂、具体工厂、抽象工厂)

7 阅读6分钟

工厂模式详解(Java版)

工厂模式是设计模式中创建型模式的核心,目的是封装对象的创建过程,让调用方无需关心对象的具体实现细节,只需要通过工厂来获取所需对象。它主要分为三种形式:简单工厂模式(不属于GOF23种设计模式,但应用广泛)、工厂方法模式抽象工厂模式

一、核心思想

工厂模式的核心是:将对象的创建与使用分离

  • 调用方:只需要“要什么”,不需要知道“怎么造”
  • 工厂:负责“造什么”和“怎么造”
  • 产品:被创建的对象

二、简单工厂模式(Simple Factory)

1. 定义

也叫“静态工厂模式”,由一个工厂类根据传入的参数,动态决定创建哪一种产品类的实例(所有产品继承同一个父类/接口)。

2. 适用场景

产品类型较少且相对固定,不需要频繁扩展新产品。

3. 代码示例

步骤1:定义产品接口
// 产品接口:所有汽车都遵循这个规范
public interface Car {
    void drive(); // 驾驶方法
}
步骤2:实现具体产品
// 具体产品1:宝马
public class BMWCar implements Car {
    @Override
    public void drive() {
        System.out.println("驾驶宝马汽车");
    }
}

// 具体产品2:奔驰
public class BenzCar implements Car {
    @Override
    public void drive() {
        System.out.println("驾驶奔驰汽车");
    }
}
步骤3:创建简单工厂
// 简单工厂类:负责创建汽车对象
public class CarSimpleFactory {
    // 静态方法:根据参数创建对应产品
    public static Car createCar(String type) {
        if ("bmw".equalsIgnoreCase(type)) {
            return new BMWCar();
        } else if ("benz".equalsIgnoreCase(type)) {
            return new BenzCar();
        } else {
            throw new IllegalArgumentException("不支持的汽车类型:" + type);
        }
    }
}
步骤4:调用方使用
public class Client {
    public static void main(String[] args) {
        // 调用方只需要传参数,无需new具体对象
        Car bmw = CarSimpleFactory.createCar("bmw");
        bmw.drive(); // 输出:驾驶宝马汽车
        
        Car benz = CarSimpleFactory.createCar("benz");
        benz.drive(); // 输出:驾驶奔驰汽车
    }
}

4. 优缺点

  • ✅ 优点:简化对象创建,解耦调用方和产品实现
  • ❌ 缺点:违反“开闭原则”(新增产品需要修改工厂类的createCar方法),工厂类职责过重

三、工厂方法模式(Factory Method)

1. 定义

将工厂抽象化,为每个产品提供一个专属工厂,新增产品时只需要新增对应的工厂和产品类,无需修改原有代码。

2. 结构

  • 抽象产品(Product):定义产品规范
  • 具体产品(Concrete Product):实现抽象产品
  • 抽象工厂(Factory):定义创建产品的抽象方法
  • 具体工厂(Concrete Factory):实现抽象工厂,创建对应的具体产品

3. 代码示例

步骤1:抽象产品(复用上面的Car接口)
步骤2:具体产品(复用BMWCar、BenzCar)
步骤3:抽象工厂
// 抽象工厂:定义创建汽车的规范
public interface CarFactory {
    Car createCar(); // 创建汽车的抽象方法
}
步骤4:具体工厂
// 宝马工厂:只创建宝马汽车
public class BMWCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new BMWCar();
    }
}

// 奔驰工厂:只创建奔驰汽车
public class BenzCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new BenzCar();
    }
}
步骤5:调用方使用
public class Client {
    public static void main(String[] args) {
        // 创建宝马工厂,生产宝马汽车
        CarFactory bmwFactory = new BMWCarFactory();
        Car bmw = bmwFactory.createCar();
        bmw.drive();
        
        // 创建奔驰工厂,生产奔驰汽车
        CarFactory benzFactory = new BenzCarFactory();
        Car benz = benzFactory.createCar();
        benz.drive();
    }
}

4. 优缺点

  • ✅ 优点:符合“开闭原则”(新增产品只需新增工厂+产品类),单一职责(每个工厂只造一种产品)
  • ❌ 缺点:类数量膨胀(新增一个产品需要新增两个类:产品类+工厂类)

四、抽象工厂模式(Abstract Factory)

1. 定义

用于创建一系列相关/相互依赖的产品族,而不是单一产品。比如:宝马工厂不仅生产宝马汽车,还生产宝马轮胎、宝马座椅;奔驰工厂对应生产奔驰轮胎、奔驰座椅。

2. 核心概念

  • 产品族:同一品牌/厂商下的所有产品(如宝马的汽车+轮胎+座椅)
  • 产品等级:不同品牌的同类型产品(如宝马轮胎、奔驰轮胎)

3. 代码示例

步骤1:定义多个抽象产品(产品族)
// 汽车接口(产品等级1)
public interface Car {
    void drive();
}

// 轮胎接口(产品等级2)
public interface Tire {
    void roll();
}

// 座椅接口(产品等级3)
public interface Seat {
    void sit();
}
步骤2:实现具体产品(分品牌)
// 宝马系列产品
public class BMWCar implements Car {
    @Override
    public void drive() { System.out.println("驾驶宝马汽车"); }
}
public class BMWTire implements Tire {
    @Override
    public void roll() { System.out.println("宝马轮胎滚动"); }
}
public class BMWSeat implements Seat {
    @Override
    public void sit() { System.out.println("坐宝马座椅"); }
}

// 奔驰系列产品
public class BenzCar implements Car {
    @Override
    public void drive() { System.out.println("驾驶奔驰汽车"); }
}
public class BenzTire implements Tire {
    @Override
    public void roll() { System.out.println("奔驰轮胎滚动"); }
}
public class BenzSeat implements Seat {
    @Override
    public void sit() { System.out.println("坐奔驰座椅"); }
}
步骤3:抽象工厂(定义产品族的创建规范)
// 抽象工厂:定义创建整个产品族的方法
public interface CarAbstractFactory {
    Car createCar();    // 创建汽车
    Tire createTire();  // 创建轮胎
    Seat createSeat();  // 创建座椅
}
步骤4:具体工厂(生产完整产品族)
// 宝马工厂:生产宝马全套产品
public class BMWFactory implements CarAbstractFactory {
    @Override
    public Car createCar() { return new BMWCar(); }
    @Override
    public Tire createTire() { return new BMWTire(); }
    @Override
    public Seat createSeat() { return new BMWSeat(); }
}

// 奔驰工厂:生产奔驰全套产品
public class BenzFactory implements CarAbstractFactory {
    @Override
    public Car createCar() { return new BenzCar(); }
    @Override
    public Tire createTire() { return new BenzTire(); }
    @Override
    public Seat createSeat() { return new BenzSeat(); }
}
步骤5:调用方使用
public class Client {
    public static void main(String[] args) {
        // 生产宝马产品族
        CarAbstractFactory bmwFactory = new BMWFactory();
        bmwFactory.createCar().drive();
        bmwFactory.createTire().roll();
        bmwFactory.createSeat().sit();
        
        // 生产奔驰产品族
        CarAbstractFactory benzFactory = new BenzFactory();
        benzFactory.createCar().drive();
        benzFactory.createTire().roll();
        benzFactory.createSeat().sit();
    }
}

4. 优缺点

  • ✅ 优点:保证产品族内的产品兼容性,解耦产品创建与使用
  • ❌ 缺点:扩展产品等级困难(比如新增“方向盘”产品等级,需要修改所有工厂类)

五、三种工厂模式对比

模式类型核心特点适用场景开闭原则
简单工厂一个工厂造所有产品(参数控制)产品少、不常扩展违反
工厂方法一个工厂造一种产品产品多、需要频繁扩展单一产品符合
抽象工厂一个工厂造一个产品族需要创建一系列相关产品(如品牌套系)扩展产品族符合,扩展产品等级违反

总结

  1. 简单工厂:入门级实现,适合产品固定的场景,核心是“参数控制创建”,但违反开闭原则;
  2. 工厂方法:对简单工厂的升级,为每个产品配专属工厂,符合开闭原则,但类数量会增加;
  3. 抽象工厂:针对“产品族”设计,适合创建一系列相关产品,核心是“产品族的统一创建”,但扩展新的产品类型成本高。

核心记住:工厂模式的本质是分离对象创建与使用,不同工厂模式的选择取决于“产品是单一的、还是系列的”、“是否需要频繁扩展”。