Bootstrap

23种设计模式-工厂方法(Factory Method)设计模式


类图: 工厂方法设计模式类图

一.什么是工厂方法设计模式?

工厂方法模式(Factory Method Pattern) 是一种创建型设计模式,它定义了一个创建对象的接口,由子类决定要实例化的具体类。工厂方法模式让类的实例化延迟到子类,从而避免了直接在代码中使用 new 关键字实例化具体类。

二. 工厂方法模式的特点

  • 解耦:将对象的创建与使用分离,降低耦合性。
  • 可扩展性强:可以通过新增具体产品类和具体工厂类来扩展产品族,而无需修改现有代码。
  • 遵循开闭原则:对扩展开放,对修改封闭。

三.工厂方法模式的结构

  • Product(抽象产品类):定义产品的接口,具体产品需要实现此接口。
  • ConcreteProduct(具体产品类):实现抽象产品接口,定义产品的具体实现。
  • Creator(抽象工厂类):定义一个创建产品对象的抽象方法。
  • ConcreteCreator(具体工厂类):实现工厂方法,负责创建具体产品对象。
    工厂方法设计模式

四.工厂方法模式的优缺点

  • 优点:
    • 减少耦合:客户端通过工厂方法与具体产品类解耦。
    • 扩展性强:通过增加新的具体工厂和产品类来支持新功能。
    • 符合设计原则:遵循单一职责和开闭原则。
  • 缺点:
    • 增加复杂性:需要为每种具体产品创建对应的工厂类,类的数量增加。
    • 限制适用场景:工厂方法适合创建少量的产品,如果产品种类非常多,代码复杂度会增加。

五.工厂方法模式的 C++ 实现

#include <iostream>
#include <memory>
using namespace std;

// 抽象产品类
class Product {
public:
    virtual void UseProduct() = 0; // 使用产品的接口
    virtual ~Product() = default;
};

// 具体产品A
class ConcreteProductA : public Product {
public:
    void UseProduct() override {
        cout << "Using ConcreteProductA" << endl;
    }
};

// 具体产品B
class ConcreteProductB : public Product {
public:
    void UseProduct() override {
        cout << "Using ConcreteProductB" << endl;
    }
};

// 抽象工厂类
class Creator {
public:
    virtual unique_ptr<Product> FactoryMethod() = 0; // 工厂方法
    virtual ~Creator() = default;
};

// 具体工厂A
class ConcreteCreatorA : public Creator {
public:
    unique_ptr<Product> FactoryMethod() override {
        return make_unique<ConcreteProductA>(); // 创建具体产品A
    }
};

// 具体工厂B
class ConcreteCreatorB : public Creator {
public:
    unique_ptr<Product> FactoryMethod() override {
        return make_unique<ConcreteProductB>(); // 创建具体产品B
    }
};

// 测试代码
int main() {
    unique_ptr<Creator> factoryA = make_unique<ConcreteCreatorA>();
    unique_ptr<Product> productA = factoryA->FactoryMethod();
    productA->UseProduct();

    unique_ptr<Creator> factoryB = make_unique<ConcreteCreatorB>();
    unique_ptr<Product> productB = factoryB->FactoryMethod();
    productB->UseProduct();

    return 0;
}

六.工厂方法模式的 Java 实现

// 抽象产品类
interface Product {
    void useProduct(); // 使用产品的接口
}

// 具体产品A
class ConcreteProductA implements Product {
    public void useProduct() {
        System.out.println("Using ConcreteProductA");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    public void useProduct() {
        System.out.println("Using ConcreteProductB");
    }
}

// 抽象工厂类
abstract class Creator {
    public abstract Product factoryMethod(); // 工厂方法
}

// 具体工厂A
class ConcreteCreatorA extends Creator {
    public Product factoryMethod() {
        return new ConcreteProductA(); // 创建具体产品A
    }
}

// 具体工厂B
class ConcreteCreatorB extends Creator {
    public Product factoryMethod() {
        return new ConcreteProductB(); // 创建具体产品B
    }
}

// 测试代码
public class FactoryMethodDemo {
    public static void main(String[] args) {
        Creator factoryA = new ConcreteCreatorA();
        Product productA = factoryA.factoryMethod();
        productA.useProduct();

        Creator factoryB = new ConcreteCreatorB();
        Product productB = factoryB.factoryMethod();
        productB.useProduct();
    }
}

七.代码解析

  1. 抽象产品类
    • Product 定义了一个抽象接口 UseProduct,所有具体产品类都必须实现此接口。
    • 通过多态,客户端代码无需关心具体产品类的类型,只需调用接口方法。
  2. 具体产品类
    • ConcreteProductA 和 ConcreteProductB 是 Product 的派生类,分别实现了 UseProduct 接口。
    • 每个具体产品类有自己的实现逻辑,例如打印不同的消息。
  3. 抽象工厂类
    • Creator 定义了一个纯虚函数 FactoryMethod,用于创建产品。
    • 通过将工厂方法定义为虚函数,使得子类可以重写以返回不同的具体产品实例。
  4. 具体工厂类
    • ConcreteCreatorA 和 ConcreteCreatorB 是 Creator 的派生类,分别重写了 FactoryMethod。
    • FactoryMethod 返回具体产品类的实例,这里使用了 C++11 的 unique_ptr 智能指针,避免了手动管理内存的复杂性。
  5. 客户端代码
    • main 函数中,首先创建工厂对象(如 ConcreteCreatorA),通过工厂对象调用 FactoryMethod 方法获取产品实例。
    • 调用产品的 UseProduct 方法进行操作。
    • 使用 unique_ptr 确保资源自动释放,无需手动销毁。

八.总结

 工厂方法模式是一种灵活的创建对象模式,适用于需要根据不同条件创建多种产品实例的场景。C++ 的实现中通过继承和多态实现工厂方法,同时使用智能指针避免了内存泄漏的问题。Java 的实现通过抽象类和具体类的组合也达到了类似效果。虽然工厂方法模式提高了代码的灵活性,但也增加了系统的复杂性,需要根据项目实际需求合理使用。
应用场景:

  • 需要灵活创建对象:如日志记录器可以根据配置创建文件日志或数据库日志实例。
  • 避免依赖具体类:如多种数据库连接类型,可以通过工厂方法动态生成。
  • 需要控制对象创建逻辑:如只允许创建特定种类的实例。
;