工厂方法模式(Factory Method Pattern)

定义

工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但将具体实例化工作推迟到子类中,使得子类可以决定实例化哪个类。该模式通过继承实现对象创建的解耦,遵循“依赖倒置原则”和“开闭原则”。​

UML 类图​

设计模式之创建型:工厂方法模式_子类

  • Creator(抽象工厂)​​:声明工厂方法(factoryMethod()),返回抽象产品类型。
  • ​​ConcreteCreator(具体工厂)​​:实现工厂方法,返回具体的产品实例。
  • Product(抽象产品)​​:定义产品的接口。
  • ConcreteProduct(具体产品)​​:实现抽象产品的接口。

核心思想​

  • 延迟实例化​​:将对象的创建逻辑从客户端代码分离,交由子类决定如何创建。
  • 解耦​​:客户端仅依赖抽象接口(Creator 和 Product),不依赖具体实现。

优点​

  • 开闭原则​​:新增产品时只需添加新工厂和产品类,无需修改现有代码。
  • 单一职责​​:每个工厂只负责创建一种产品,逻辑清晰。
  • 扩展性高​​:支持动态切换产品(如通过配置文件或依赖注入)。
  • 降低耦合​​:客户端代码仅依赖抽象接口,与具体实现解耦。

缺点​​

  • 类数量膨胀​​:每新增一个产品需新增工厂和产品类,增加系统复杂度。
  • ​​抽象层理解成本​​:需设计合理的抽象接口,对新手可能不够直观。
  • ​​间接性​​:客户端需通过工厂获取对象,不如直接实例化简单。

适用场景​

  • 未知具体产品类型​​:客户端不需要知道创建的具体类(如插件系统)。
  • 支持未来扩展​​:预期系统会新增产品类型(如日志记录器、数据库连接器)。
  • ​​对象创建依赖子类​​:希望子类决定创建逻辑(如框架设计)。
  • ​​复用对象创建逻辑​​:多个子类需共享相同创建流程,但细节不同。

案例

UML 类图​

设计模式之创建型:工厂方法模式_子类_02

Factory

/**
 * 工厂标准 Creator
 */
public interface Factory {

    /**
     * 创建产品,factoryMethod 方法
     *
     * @return 符合标准的产品
     */
    Product createProduct();

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

Product

/**
 * 产品标准
 */
public interface Product {

    /**
     * 获取产品名称
     * @return 产品名称
     */
    String getName();

}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

FactoryA

/**
 * 一家生产 A 类型的产品 的工厂
 */
public class FactoryA implements Factory {
    @Override
    public Product createProduct() {
        return new ProductA();
    }
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

FactoryB

/**
 * 一家生产 B 类型的产品 的工厂
 */
public class FactoryB implements Factory {
    @Override
    public Product createProduct() {
        return new ProductB();
    }
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

ProductA

/**
 * A 类型的产品
 */
public class ProductA implements Product {

    public ProductA() {
        System.out.println("a product A has been generated and completed.");
    }

    @Override
    public String getName() {
        return "product A";
    }
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

ProductB

/**
 * B 类型的产品
 */
public class ProductB implements Product {

    public ProductB() {
        System.out.println("a product B has been generated and completed.");
    }

    @Override
    public String getName() {
        return "product B";
    }
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

Client

/**
 * 现在来了一笔订单,需要 一个 ProductA 和 ProductB
 * 告知工厂A 和 工厂B 开始生产。
 */
public class Client {

    public static void main(String[] args) {
        Factory factoryA = new FactoryA();
        Product productA = factoryA.createProduct();
        System.out.println(productA.getName());

        Factory factoryB = new FactoryB();
        Product productB = factoryB.createProduct();
        System.out.println(productB.getName());
    }

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

之后 现在又来了一笔订单,需要 一个 ProductA、ProductB 和 ProductC
这时,只需要扩展 ProductC 的定义和 一家生产 C 类型的产品 的工厂 FactoryC 即可,不需要改动原有产品及工厂。

ProductC

/**
 * C 类型的产品
 */
public class ProductC implements Product {

    public ProductC() {
        System.out.println("a product C has been generated and completed.");
    }

    @Override
    public String getName() {
        return "product C";
    }
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

FactoryC

/**
 * 一家生产 C 类型的产品 的工厂
 */
public class FactoryC implements Factory {
    @Override
    public Product createProduct() {
        return new ProductC();
    }
}

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

注意: 这里工厂也可以是产品线,这和现实世界时一样的,根据实际需要动态调整。