工厂方法模式 (Factory Method)
工厂方法模式是一种创建型设计模式,提供一个创建对象的接口,让子类决定实例化哪个类,从而实现了对对象创建过程的解耦和扩展。
意图
- 定义一个用于创建对象的接口,允许子类决定具体实例化哪个类。
- 把对象创建的职责交给子类,使得系统更灵活,符合 开闭原则。
使用场景
- 运行时决定类的实例化
- 如果对象的具体类型在编译时无法确定,而需要在运行时根据条件选择。
- 隐藏对象的复杂创建过程
- 如果创建对象的过程复杂且容易重复,可以使用工厂方法集中管理。
- 需要对对象的创建进行扩展
- 当需要新增产品类时,可以通过增加新的具体工厂类,而不修改已有代码。
参与者角色
-
工厂基类 (Creator)
- 定义创建产品对象的接口,通常包含一个抽象的
createProduct()
方法。 - 有时可以包含产品创建的默认实现。
- 定义创建产品对象的接口,通常包含一个抽象的
-
具体工厂类 (Concrete Creator)
- 实现
createProduct()
方法,负责实例化具体的产品。
- 实现
-
产品基类 (Product)
- 定义所有产品的公共接口。
-
具体产品类 (Concrete Product)
- 实现产品基类的接口,提供产品的具体功能。
示例代码
以下示例通过工厂方法模式实现了动态创建产品的功能。
cpp
#include <iostream>
#include <memory>
// 产品基类
class Product {
public:
virtual void use() const = 0;
virtual ~Product() {}
};
// 具体产品 A
class ConcreteProductA : public Product {
public:
void use() const override {
std::cout << "Using Product A" << std::endl;
}
};
// 具体产品 B
class ConcreteProductB : public Product {
public:
void use() const override {
std::cout << "Using Product B" << std::endl;
}
};
// 工厂基类
class Factory {
public:
virtual std::unique_ptr<Product> createProduct() const = 0;
virtual ~Factory() {}
};
// 具体工厂 A
class FactoryA : public Factory {
public:
std::unique_ptr<Product> createProduct() const override {
return std::make_unique<ConcreteProductA>();
}
};
// 具体工厂 B
class FactoryB : public Factory {
public:
std::unique_ptr<Product> createProduct() const override {
return std::make_unique<ConcreteProductB>();
}
};
// 主函数
int main() {
FactoryA factoryA;
FactoryB factoryB;
auto productA = factoryA.createProduct();
auto productB = factoryB.createProduct();
productA->use(); // 输出:Using Product A
productB->use(); // 输出:Using Product B
return 0;
}
代码解析
1. 产品基类
定义了所有产品的公共接口,确保具体产品具有一致的功能。例如:
cpp
class Product {
public:
virtual void use() const = 0;
virtual ~Product() {}
};
2. 具体产品类
具体产品类实现了产品基类接口,并提供具体的功能实现:
cpp
class ConcreteProductA : public Product {
public:
void use() const override {
std::cout << "Using Product A" << std::endl;
}
};
3. 工厂基类
工厂基类声明了创建产品的接口,具体工厂将实现该接口:
cpp
class Factory {
public:
virtual std::unique_ptr<Product> createProduct() const = 0;
virtual ~Factory() {}
};
4. 具体工厂类
每个具体工厂类实现了 createProduct()
方法,并实例化具体的产品:
cpp
class FactoryA : public Factory {
public:
std::unique_ptr<Product> createProduct() const override {
return std::make_unique<ConcreteProductA>();
}
};
5. 主函数
客户端代码通过工厂接口创建产品,而无需知道具体产品的实现细节:
cpp
FactoryA factoryA;
auto productA = factoryA.createProduct();
productA->use(); // 输出:Using Product A
优缺点
优点
- 符合开闭原则
- 新增产品只需新增具体工厂类,无需修改已有代码。
- 解耦
- 客户端代码只依赖于工厂接口和产品接口,具体产品的实现细节被隐藏。
- 灵活性
- 可以动态选择和创建具体产品。
缺点
- 增加复杂性
- 每个产品都需要对应的具体工厂类,可能导致类的数量增加。
- 需要额外的抽象
- 增加了工厂基类和产品基类的抽象层。
适用场景
- 动态选择产品:如根据配置文件决定创建哪个产品。
- 封装复杂创建过程:如隐藏产品创建的复杂逻辑。
- 需要扩展性:如未来可能新增产品类型。
改进与扩展
-
结合配置文件
动态读取配置,根据配置内容选择具体工厂:
cppstd::unique_ptr<Factory> factory; if (config == "A") { factory = std::make_unique<FactoryA>(); } else { factory = std::make_unique<FactoryB>(); } auto product = factory->createProduct(); product->use();
-
结合抽象工厂模式
如果需要创建一组相关的产品,可以将工厂方法扩展为抽象工厂模式。
总结
工厂方法模式通过定义创建对象的接口,将对象的创建与使用分离,提高了代码的扩展性和灵活性。
它适合需要动态选择产品类型或需要隐藏对象创建细节的场景。