简单工厂模式属于创建型设计模式的一种,核心思路是把对象的创建逻辑封装到一个独立的工厂类中,客户端只需要传入对应的参数,就可以获取到需要的产品对象,不需要直接实例化具体的产品类。这种方式可以让客户端代码和产品类的实现解耦,后续如果需要新增产品类,只需要修改工厂类的逻辑即可,不用改动客户端的调用代码。

简单工厂模式的核心角色
一个完整的简单工厂模式通常包含三个核心角色,每个角色的职责划分非常清晰:
- 抽象产品类:是所有具体产品类的公共父类,定义了所有产品都需要实现的公共接口,客户端面向这个抽象类编程即可。
- 具体产品类:继承抽象产品类,实现具体的业务逻辑,是工厂类最终创建的对象类型。
- 工厂类:核心角色,包含一个静态的创建方法,根据传入的参数判断需要创建哪种具体产品类的实例,并返回抽象产品类型的指针或引用。
C++实现简单工厂模式示例
下面以计算器的功能为例,实现一个支持加法和减法运算的简单工厂模式。首先定义抽象产品类Operation,作为所有运算类的父类:
// 抽象产品类:运算基类
class Operation {
public:
// 纯虚函数,定义运算的接口
virtual double calculate(double a, double b) = 0;
// 虚析构函数,保证多态删除时正确释放内存
virtual ~Operation() = default;
};
接下来定义两个具体产品类,分别是加法运算类和减法运算类,都继承Operation并实现calculate方法:
// 具体产品类:加法运算
class AddOperation : public Operation {
public:
double calculate(double a, double b) override {
return a + b;
}
};
// 具体产品类:减法运算
class SubOperation : public Operation {
public:
double calculate(double a, double b) override {
return a - b;
}
};
然后实现工厂类OperationFactory,包含一个静态的创建方法,根据传入的运算符参数返回对应的运算实例:
// 工厂类
class OperationFactory {
public:
// 静态创建方法,根据运算符返回对应的运算对象
static Operation* createOperation(char op) {
switch (op) {
case '+':
return new AddOperation();
case '-':
return new SubOperation();
default:
// 不支持的运算符返回空指针
return nullptr;
}
}
};
最后客户端的使用方式如下,只需要调用工厂类的创建方法,传入对应的参数就可以获取运算对象,不需要直接实例化AddOperation或者SubOperation:
#include <iostream>
int main() {
// 创建加法对象
Operation* addOp = OperationFactory::createOperation('+');
if (addOp != nullptr) {
std::cout << "1 + 2 = " << addOp->calculate(1, 2) << std::endl;
delete addOp; // 释放内存
}
// 创建减法对象
Operation* subOp = OperationFactory::createOperation('-');
if (subOp != nullptr) {
std::cout << "5 - 3 = " << subOp->calculate(5, 3) << std::endl;
delete subOp; // 释放内存
}
// 测试不支持的运算符
Operation* invalidOp = OperationFactory::createOperation('*');
if (invalidOp == nullptr) {
std::cout << "不支持的运算符" << std::endl;
}
return 0;
}
简单工厂模式的优缺点
简单工厂模式的优点非常明显,首先是实现了对象创建和使用的分离,客户端不需要知道具体产品类的类名和创建细节,只需要依赖抽象产品和工厂类即可,降低了代码的耦合度。其次如果需要新增产品类,只需要新增具体产品类并修改工厂类的创建逻辑,客户端的代码不需要改动,符合开闭原则的部分要求。
但它也存在局限性,最突出的问题是工厂类的职责过重,所有的创建逻辑都集中在工厂类中,如果产品类型非常多,工厂类的createOperation方法会变得非常臃肿,而且如果需要新增产品类,必须修改工厂类的代码,这违反了开闭原则的严格定义。因此简单工厂模式更适合产品类型比较少、创建逻辑不复杂的场景,如果产品类型较多或者后续扩展频繁,可以考虑使用工厂方法模式或者抽象工厂模式。
注意事项
在实际使用C++实现简单工厂模式时,需要注意内存管理的问题,因为工厂类返回的是堆上创建的对象指针,客户端使用完成后需要手动释放内存,否则会造成内存泄漏。如果担心手动释放的问题,也可以使用智能指针来管理返回的对象,比如返回std::unique_ptr<Operation>,这样对象会在离开作用域时自动释放,不需要手动调用delete。
另外,工厂类的创建方法通常定义为静态方法,这样客户端不需要实例化工厂类就可以直接调用,使用起来更加方便,但静态方法也有局限性,就是不能被重写,所以这也是简单工厂模式不容易扩展的原因之一。