工厂模式(Factory Pattern)
·
工厂模式是一种创建型设计模式,核心思想是:将对象的创建逻辑与使用逻辑分离,通过专门的 “工厂类” 负责创建对象,客户端无需关心对象的具体创建细节(如构造函数参数、子类选择等),只需通过工厂获取实例。
它主要解决 “对象创建复杂、耦合度高” 的问题,常见有 3 种细分形式:简单工厂模式(入门)、工厂方法模式(解耦工厂与产品)、抽象工厂模式(多产品族创建)。
一、核心原理
1. 解决的问题
- 客户端直接
new对象会导致耦合度高(需知道具体类名、构造细节)。 - 若对象创建逻辑复杂(如多子类选择、参数校验、初始化流程),直接写在客户端会冗余且难维护。
- 需统一管理对象创建(如单例、池化、日志记录)。
2. 核心角色(通用)
| 角色 | 职责 |
|---|---|
| 产品(Product) | 定义工厂要创建的对象的统一接口(或抽象类),是所有具体产品的基类。 |
| 具体产品(ConcreteProduct) | 实现产品接口的具体对象(如 “苹果手机”“华为手机”)。 |
| 工厂(Factory) | 负责创建产品的核心类,提供创建产品的方法(静态或实例方法),封装创建逻辑。 |
3. 设计关键
- 面向接口编程:客户端依赖产品接口而非具体产品,工厂返回接口类型,降低耦合。
- 封装创建逻辑:将
new操作、子类选择、参数处理等放在工厂中,客户端仅调用工厂方法。
二、三种工厂模式的 C++ 实现
(一)简单工厂模式(Simple Factory)
原理
- 一个工厂类 + 一个产品接口 + 多个具体产品。
- 工厂通过 “参数判断” 创建对应具体产品,客户端传入参数即可获取实例。
- 优点:简单直观;缺点:工厂类与具体产品强耦合,新增产品需修改工厂代码(违反 “开闭原则”)。
示例:手机工厂(创建不同品牌手机)
#include <iostream>
#include <string>
using namespace std;
// 1. 产品接口(统一手机功能)
class Phone {
public:
virtual ~Phone() = default; // 基类析构设为虚函数,避免内存泄漏
virtual void showBrand() const = 0; // 纯虚函数:展示品牌
};
// 2. 具体产品1:苹果手机
class IPhone : public Phone {
public:
void showBrand() const override {
cout << "我是苹果手机(IPhone)" << endl;
}
};
// 3. 具体产品2:华为手机
class HuaweiPhone : public Phone {
public:
void showBrand() const override {
cout << "我是华为手机(Huawei)" << endl;
}
};
// 4. 简单工厂类(核心:根据参数创建产品)
class PhoneFactory {
public:
// 静态工厂方法:传入品牌参数,返回对应手机实例
static Phone* createPhone(const string& brand) {
if (brand == "IPhone") {
return new IPhone();
} else if (brand == "Huawei") {
return new HuaweiPhone();
} else {
cout << "不支持的手机品牌!" << endl;
return nullptr;
}
}
};
// 客户端使用
int main() {
// 客户端无需知道 IPhone/HuaweiPhone 的创建细节,仅调用工厂方法
Phone* phone1 = PhoneFactory::createPhone("IPhone");
if (phone1) {
phone1->showBrand(); // 输出:我是苹果手机(IPhone)
delete phone1;
}
Phone* phone2 = PhoneFactory::createPhone("Huawei");
if (phone2) {
phone2->showBrand(); // 输出:我是华为手机(Huawei)
delete phone2;
}
Phone* phone3 = PhoneFactory::createPhone("Xiaomi"); // 输出:不支持的手机品牌!
delete phone3;
return 0;
}
(二)工厂方法模式(Factory Method)
原理
- 一个产品接口 + 多个具体产品 + 一个工厂接口 + 多个具体工厂(每个具体产品对应一个具体工厂)。
- 工厂接口定义创建产品的方法,具体工厂实现该方法创建对应产品。
- 优点:遵循 “开闭原则”,新增产品只需新增具体产品类和具体工厂类,无需修改原有代码;缺点:类数量增多(产品和工厂一一对应)。
示例:手机工厂(每个品牌对应专属工厂)
#include <iostream>
#include <string>
using namespace std;
// 1. 产品接口(与简单工厂一致)
class Phone {
public:
virtual ~Phone() = default;
virtual void showBrand() const = 0;
};
// 2. 具体产品(与简单工厂一致)
class IPhone : public Phone {
public:
void showBrand() const override { cout << "我是苹果手机(IPhone)" << endl; }
};
class HuaweiPhone : public Phone {
public:
void showBrand() const override { cout << "我是华为手机(Huawei)" << endl; }
};
// 3. 工厂接口(定义创建产品的方法)
class PhoneFactory {
public:
virtual ~PhoneFactory() = default;
virtual Phone* createPhone() const = 0; // 纯虚函数:创建手机(具体由子类实现)
};
// 4. 具体工厂1:苹果工厂(仅创建苹果手机)
class IPhoneFactory : public PhoneFactory {
public:
Phone* createPhone() const override {
return new IPhone();
}
};
// 5. 具体工厂2:华为工厂(仅创建华为手机)
class HuaweiFactory : public PhoneFactory {
public:
Phone* createPhone() const override {
return new HuaweiPhone();
}
};
// 客户端使用
int main() {
// 要创建苹果手机:实例化苹果工厂,调用工厂方法
PhoneFactory* factory1 = new IPhoneFactory();
Phone* phone1 = factory1->createPhone();
phone1->showBrand(); // 输出:我是苹果手机(IPhone)
delete phone1;
delete factory1;
// 要创建华为手机:实例化华为工厂,调用工厂方法
PhoneFactory* factory2 = new HuaweiFactory();
Phone* phone2 = factory2->createPhone();
phone2->showBrand(); // 输出:我是华为手机(Huawei)
delete phone2;
delete factory2;
return 0;
}
(三)抽象工厂模式(Abstract Factory)
原理
- 多个产品接口(产品族) + 多个具体产品族 + 一个抽象工厂接口 + 多个具体工厂(每个工厂负责一个产品族的创建)。
- 核心是 “产品族”:一组相关联的产品(如 “苹果手机 + 苹果电脑”“华为手机 + 华为电脑”)。
- 优点:统一创建产品族,保证产品兼容性;缺点:新增产品族需修改抽象工厂接口(违反 “开闭原则”),适合产品族稳定的场景。
示例:电子设备工厂(创建手机 + 电脑的产品族)
#include <iostream>
#include <string>
using namespace std;
// -------------------------- 产品族接口 --------------------------
// 产品1接口:手机
class Phone {
public:
virtual ~Phone() = default;
virtual void showBrand() const = 0;
};
// 产品2接口:电脑
class Computer {
public:
virtual ~Computer() = default;
virtual void showBrand() const = 0;
};
// -------------------------- 具体产品族1:苹果系列 --------------------------
class IPhone : public Phone {
public:
void showBrand() const override { cout << "苹果手机(IPhone 15)" << endl; }
};
class MacBook : public Computer {
public:
void showBrand() const override { cout << "苹果电脑(MacBook Pro)" << endl; }
};
// -------------------------- 具体产品族2:华为系列 --------------------------
class HuaweiPhone : public Phone {
public:
void showBrand() const override { cout << "华为手机(Mate 60)" << endl; }
};
class HuaweiPC : public Computer {
public:
void showBrand() const override { cout << "华为电脑(MateBook X Pro)" << endl; }
};
// -------------------------- 抽象工厂接口(定义产品族的创建方法) --------------------------
class ElectronicFactory {
public:
virtual ~ElectronicFactory() = default;
virtual Phone* createPhone() const = 0; // 创建手机
virtual Computer* createComputer() const = 0; // 创建电脑
};
// -------------------------- 具体工厂1:苹果工厂(创建苹果产品族) --------------------------
class AppleFactory : public ElectronicFactory {
public:
Phone* createPhone() const override {
return new IPhone();
}
Computer* createComputer() const override {
return new MacBook();
}
};
// -------------------------- 具体工厂2:华为工厂(创建华为产品族) --------------------------
class HuaweiFactory : public ElectronicFactory {
public:
Phone* createPhone() const override {
return new HuaweiPhone();
}
Computer* createComputer() const override {
return new HuaweiPC();
}
};
// 客户端使用
int main() {
// 1. 购买苹果产品族
ElectronicFactory* appleFactory = new AppleFactory();
Phone* iphone = appleFactory->createPhone();
Computer* mac = appleFactory->createComputer();
cout << "苹果产品族:" << endl;
iphone->showBrand(); // 输出:苹果手机(IPhone 15)
mac->showBrand(); // 输出:苹果电脑(MacBook Pro)
delete iphone;
delete mac;
delete appleFactory;
// 2. 购买华为产品族
ElectronicFactory* huaweiFactory = new HuaweiFactory();
Phone* huaweiPhone = huaweiFactory->createPhone();
Computer* huaweiPC = huaweiFactory->createComputer();
cout << "\n华为产品族:" << endl;
huaweiPhone->showBrand(); // 输出:华为手机(Mate 60)
huaweiPC->showBrand(); // 输出:华为电脑(MateBook X Pro)
delete huaweiPhone;
delete huaweiPC;
delete huaweiFactory;
return 0;
}
输出结果:
苹果产品族:
苹果手机(IPhone 15)
苹果电脑(MacBook Pro)
华为产品族:
华为手机(Mate 60)
华为电脑(MateBook X Pro)
三、三种工厂模式的对比与选择
| 模式类型 | 核心特点 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 简单工厂模式 | 一个工厂创建所有产品(参数判断) | 代码简单,客户端使用便捷 | 违反开闭原则,新增产品需修改工厂 | 产品数量少、变化少(如工具类创建) |
| 工厂方法模式 | 产品与工厂一一对应(工厂接口 + 具体工厂) | 遵循开闭原则,扩展灵活 | 类数量增多(产品 + 工厂) | 产品数量较多、需频繁扩展(如插件系统) |
| 抽象工厂模式 | 一个工厂创建一个产品族(多产品接口) | 保证产品族兼容性,统一创建逻辑 | 新增产品族需修改抽象工厂接口 | 需创建一组相关联的产品(如软硬件套装) |
四、关键注意事项
- 内存管理:示例中用裸指针创建对象,实际开发中建议使用
std::unique_ptr/std::shared_ptr智能指针,避免内存泄漏(如return std::make_unique<IPhone>())。 - 接口一致性:产品类需继承统一接口,工厂方法返回接口类型,确保客户端可统一使用。
- 避免过度设计:若产品简单(无多子类、创建逻辑简单),直接
new即可,无需强行使用工厂模式。 - 线程安全:若工厂方法是静态的或全局工厂,多线程环境下需注意创建逻辑的线程安全(如加锁、使用原子操作)。
五、总结
工厂模式的核心价值是 “分离对象的创建与使用”:
- 降低耦合:客户端无需依赖具体产品类,仅依赖工厂和产品接口。
- 便于维护:对象创建逻辑集中在工厂,修改时只需改工厂代码。
- 灵活扩展:根据业务场景选择不同工厂模式(简单工厂适合简单场景,工厂方法 / 抽象工厂适合复杂场景)。
它是实际开发中最常用的设计模式之一,例如框架中的对象创建(如 Spring 的 BeanFactory)、插件系统、配置化创建对象等场景都有广泛应用。
更多推荐

所有评论(0)