前言
工厂模式的核心思想是将对象的创建隐藏到工厂内部,而不是暴露在代码调用处
一、简单工厂模式
1.1、属于创建型模式
绕开new,避免对象创建过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。
为什么使用创建型模式?
在软件系统种,由于需求的变化,需要创建的对象的具体类型变化经常变化。
1.2、说明
简单工厂模式,并不在GoF的23中设计模式当中,但它确实工厂模式的一个基础。
1.3、核心思想
定义一个工厂类,根据传入的参数不同,返回不同的产品实例。<========>通过参数告诉需求,然后根据需求返回不同的实例,不过多关注实例的实现。
1.4、为什么要用简单工厂模式
经典问题场景:
拥有一个图形绘制程序,需要创建不同形状:
cpp
// 糟糕的实现:客户端需要知道所有具体类
class Circle {
public:
void draw() { cout << "绘制圆形" << endl; }
};
class Rectangle {
public:
void draw() { cout << "绘制矩形" << endl; }
};
class Triangle {
public:
void draw() { cout << "绘制三角形" << endl; }
};
// 客户端代码
void drawShape(const string& type) {
if (type == "circle") {
Circle shape;
shape.draw();
} else if (type == "rectangle") {
Rectangle shape;
shape.draw();
} else if (type == "triangle") {
Triangle shape;
shape.draw();
}
// 每增加一个形状,就要修改这里的if-else!
}
问题点:
- 客户端与具体类紧密耦合
- 违反 开闭原则,如果要增加新的形状类,就需要修改客户端代码
使用简单工厂模式之后
- 定义产品接口
cpp
// 抽象产品类
class Shape {
public:
virtual ~Shape() = default;
virtual void draw() const = 0;
virtual string getName() const = 0;
};
- 定义具体产品类
cpp
// 具体产品类
class Circle : public Shape {
public:
void draw() const override {
cout << "绘制圆形" << endl;
}
string getName() const override {
return "圆形";
}
};
class Rectangle : public Shape {
public:
void draw() const override {
cout << "绘制矩形" << endl;
}
string getName() const override {
return "矩形";
}
};
class Triangle : public Shape {
public:
void draw() const override {
cout << "绘制三角形" << endl;
}
string getName() const override {
return "三角形";
}
};
- 创建工厂类(核心点)
cpp
// 简单工厂类
class ShapeFactory {
public:
// 静态工厂方法,根据类型字符串创建对象
static unique_ptr<Shape> createShape(const string& type) {
if (type == "circle") {
return make_unique<Circle>();
} else if (type == "rectangle") {
return make_unique<Rectangle>();
} else if (type == "triangle") {
return make_unique<Triangle>();
} else {
throw invalid_argument("未知的形状类型: " + type);
}
}
// 也可以使用枚举来避免字符串硬编码
enum class ShapeType { CIRCLE, RECTANGLE, TRIANGLE };
static unique_ptr<Shape> createShape(ShapeType type) {
switch (type) {
case ShapeType::CIRCLE:
return make_unique<Circle>();
case ShapeType::RECTANGLE:
return make_unique<Rectangle>();
case ShapeType::TRIANGLE:
return make_unique<Triangle>();
default:
throw invalid_argument("未知的形状类型");
}
}
};
- 客户端代码
cpp
// 客户端代码 - 变得非常简洁!
void demo() {
cout << "=== 简单工厂模式演示 ===" << endl;
try {
// 使用字符串创建
auto circle = ShapeFactory::createShape("circle");
auto rectangle = ShapeFactory::createShape("rectangle");
auto triangle = ShapeFactory::createShape("triangle");
circle->draw();
rectangle->draw();
triangle->draw();
cout << "------------------------" << endl;
// 使用枚举创建(更安全)
auto circle2 = ShapeFactory::createShape(ShapeFactory::ShapeType::CIRCLE);
auto rect2 = ShapeFactory::createShape(ShapeFactory::ShapeType::RECTANGLE);
cout << "形状: " << circle2->getName() << endl;
circle2->draw();
} catch (const exception& e) {
cout << "错误: " << e.what() << endl;
}
}
附上UML类图

1.4、优缺点
| 优点 | 缺点 |
|---|---|
| 客户端与具体类解耦 | 违反开闭原则,每新增一个产品就需要修改工厂类 |
| 集中化对象创建 | 工厂类职责过重,所有创建逻辑集中在一个类中 |
| 便于统一管理 | 产品较多时代码会显得臃肿 |
| 隐藏创建细节 | 不易于扩展 |
1.5、适用场景
- 支付系统(支付宝,微信,现金,银行卡等支付方式)
- 数据库连接(
MySql,SQLite,Oracle等) - 日志系统(创建文件日志,控制台日志,数据库日志等)
如果只有2~3种产品,直接new会更简单,不要为了用而用,从而过度设计
1.5、简单工厂的变种:
利用注册
cpp
// 使用注册表避免if-else链
class ShapeFactory {
private:
using Creator = std::function<std::unique_ptr<Shape>()>;
static std::unordered_map<std::string, Creator> registry;
public:
static void registerShape(const std::string& type, Creator creator) {
registry[type] = creator;
}
static std::unique_ptr<Shape> createShape(const std::string& type) {
auto it = registry.find(type);
if (it != registry.end()) {
return it->second();
}
throw std::invalid_argument("未知类型: " + type);
}
};
// 注册具体产品
class ShapeRegistrar {
public:
ShapeRegistrar(const std::string& type) {
ShapeFactory::registerShape(type, []() {
return std::make_unique<Circle>();
});
}
};
// 自动注册
static ShapeRegistrar circleRegistrar("circle");
二、工厂方法模式
2.1、核心思想
定义一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
2.2、与简单工厂的关键区别
简单工厂把创建逻辑集中在一个类中,而工厂方法模式将创建逻辑分散到各个子类中。
2.3、代码展示
- 定义抽象产品类
cpp
// 抽象产品
class Document {
public:
virtual ~Document() = default;
virtual void open() = 0;
virtual void save() = 0;
virtual std::string getType() const = 0;
};
- 定义具体产品类
cpp
// 具体产品
class WordDocument : public Document {
public:
void open() override {
std::cout << "打开Word文档,显示文字处理界面" << std::endl;
}
void save() override {
std::cout << "保存为.docx格式" << std::endl;
}
std::string getType() const override {
return "Word文档";
}
};
class ExcelDocument : public Document {
public:
void open() override {
std::cout << "打开Excel文档,显示表格界面" << std::endl;
}
void save() override {
std::cout << "保存为.xlsx格式" << std::endl;
}
std::string getType() const override {
return "Excel文档";
}
};
class PdfDocument : public Document {
public:
void open() override {
std::cout << "打开PDF文档,显示只读内容" << std::endl;
}
void save() override {
std::cout << "PDF文档不支持编辑保存" << std::endl;
}
std::string getType() const override {
return "PDF文档";
}
};
- 定义工厂类
cpp
class Application {
public:
virtual ~Application() = default;
// 工厂方法 - 由子类实现
virtual std::unique_ptr<Document> createDocument() = 0;
// 业务方法
void newDocument() {
std::cout << "创建新文档..." << std::endl;
auto doc = createDocument(); // 调用工厂方法
doc->open();
documents_.push_back(std::move(doc));
}
void listDocuments() {
std::cout << "当前打开的文档:" << std::endl;
for (const auto& doc : documents_) {
std::cout << " - " << doc->getType() << std::endl;
}
}
private:
std::vector<std::unique_ptr<Document>> documents_;
};
- 定义具体创建子类
cpp
// 具体创建者
class WordApplication : public Application {
public:
std::unique_ptr<Document> createDocument() override {
return std::make_unique<WordDocument>();
}
};
class ExcelApplication : public Application {
public:
std::unique_ptr<Document> createDocument() override {
return std::make_unique<ExcelDocument>();
}
};
class PdfApplication : public Application {
public:
std::unique_ptr<Document> createDocument() override {
return std::make_unique<PdfDocument>();
}
};
- 客户端代码
cpp
void demoFactoryMethod() {
std::cout << "=== 工厂方法模式演示 ===" << std::endl;
auto wordApp = std::make_unique<WordApplication>();
wordApp->newDocument(); // 创建Word文档
wordApp->listDocuments();
std::cout << "------------------------" << std::endl;
auto excelApp = std::make_unique<ExcelApplication>();
excelApp->newDocument(); // 创建Excel文档
excelApp->listDocuments();
}
2.4、补充
cpp
// 模板工厂方法 - 编译期多态
template<typename Product>
class GenericCreator {
public:
static std::unique_ptr<Product> create() {
return std::make_unique<Product>();
}
};
// 使用
auto doc = GenericCreator<WordDocument>::create();
附上UML类图

三、抽象工厂模式
3.1、核心思想
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
***注意:***创建的是产品家族,而不是单个产品
3.2、代码展示
- 定义抽象产品类
cpp
// 抽象产品 - UI组件
class Button {
public:
virtual ~Button() = default;
virtual void render() const = 0;
};
class TextField {
public:
virtual ~TextField() = default;
virtual void render() const = 0;
};
class CheckBox {
public:
virtual ~CheckBox() = default;
virtual void render() const = 0;
};
- 定义具体产品类
cpp
// 具体产品
class WinButton : public Button {
public:
void render() const override {
std::cout << "渲染Windows风格的按钮" << std::endl;
}
};
class MacButton : public Button {
public:
void render() const override {
std::cout << "渲染MacOS风格的按钮" << std::endl;
}
};
class WinTextField : public TextField {
public:
void render() const override {
std::cout << "渲染Windows风格文本框" << std::endl;
}
};
- 定义抽象工厂类
cpp
class GUIFactory {
public:
virtual ~GUIFactory() = default;
virtual std::unique_ptr<Button> createButton() = 0;
virtual std::unique_ptr<TextField> createTextField() = 0;
virtual std::unique_ptr<CheckBox> createCheckBox() = 0;
};
- 定义具体工厂类
cpp
class WinFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<WinButton>();
}
std::unique_ptr<TextField> createTextField() override {
return std::make_unique<WinTextField>();
}
std::unique_ptr<CheckBox> createCheckBox() override {
return std::make_unique<WinCheckBox>();
}
};
class MacFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<MacButton>();
}
std::unique_ptr<TextField> createTextField() override {
return std::make_unique<MacTextField>();
}
std::unique_ptr<CheckBox> createCheckBox() override {
return std::make_unique<MacCheckBox>();
}
};
- 客户端代码
cpp
class ApplicationUI {
private:
std::unique_ptr<GUIFactory> factory_;
public:
ApplicationUI(std::unique_ptr<GUIFactory> factory)
: factory_(std::move(factory)) {}
void createUI() {
std::cout << "\n=== 创建应用界面 ===" << std::endl;
auto button = factory_->createButton();
auto checkbox = factory_->createCheckbox();
auto textbox = factory_->createTextBox();
button->render();
button->onClick();
checkbox->render();
checkbox->onCheck();
textbox->render();
textbox->onInput();
}
};
// 使用示例
void demoAbstractFactory() {
std::cout << "=== 抽象工厂模式演示 ===" << std::endl;
// Windows风格界面
auto windowsUI = ApplicationUI(std::make_unique<WindowsFactory>());
windowsUI.createUI();
// macOS风格界面
auto macUI = ApplicationUI(std::make_unique<MacFactory>());
macUI.createUI();
// Linux风格界面
auto linuxUI = ApplicationUI(std::make_unique<LinuxFactory>());
linuxUI.createUI();
}
3.3、补充
cpp
// 使用variant返回不同类型产品
class ModernGUIFactory {
public:
using ButtonVariant = std::variant<WinButton, MacButton, LinuxButton>;
virtual ButtonVariant createButton() = 0;
virtual auto createTextField() = 0; // 自动推导返回类型
};
四、实战
以魔兽世界为例:游戏中存在多种角色(战士,法师,武僧,术士,猎人等);利用工厂模式实现角色创建系统。
cpp
// 定义角色的基本属性
class Character
{
protected:
std::string name; // 角色名称
int health; // 生命值
int attack; // 攻击力
int defense; // 防御力
int magic; // 魔法值
public:
Character(const std::string& name, int health, int attack, int defense, int magic)
: name(name), health(health), attack(attack), defense(defense), magic(magic) {}
virtual ~Character() = default;
virtual void PrintInfo() const
{
std::cout << "角色名称: " << name
<< ", 生命值: " << health
<< ", 攻击力: " << attack
<< ", 防御力: " << defense
<< ", 魔法值: " << magic << std::endl;
}
virtual void SpecialSkill() = 0;
std::string GetName() const { return name; }
};
// 定义具体角色
// 战士
class Warrior : public Character
{
public:
Warrior(const std::string& name)
: Character(name, 150, 80, 80, 20) {
}
void SpecialSkill() override
{
std::cout << "战士技能:冲锋" << std::endl;
}
void PrintInfo() const override;
{
std::cout << "战士名称: " << name << std::endl;
Character::PrintInfo();
std::cout << "特点:近战攻击,攻击力高" << std::endl;
}
};
// 法师
class Mage : public Character
{
public:
Mage(const std::string& name)
: Character(name, 80, 30, 40, 120) {
}
void SpecialSkill() override
{
std::cout << "法师技能:火球术" << std::endl;
}
void PrintInfo() const override
{
std::cout << "法师名称: " << name << std::endl;
Character::PrintInfo();
std::cout << "特点:魔法攻击,高魔法值" << std::endl;
}
};
// 武僧
class Monk : public Character
{
public:
Monk(const std::string& name)
: Character(name, 100, 80, 80, 80) {
}
void SpecialSkill() override
{
std::cout << "武僧技能:禅意拳" << std::endl;
}
void PrintInfo() const override
{
std::cout << "武僧名称: " << name << std::endl;
Character::PrintInfo();
std::cout << "特点:近战高攻防,平衡属性" << std::endl;
}
};
简单工厂
cpp
// 枚举每一种角色
enum class CharacterType
{
Warrior, Mage, Monk
};
// 简单工厂类,根据类型创建角色
class SimpleCharacterFactory
{
public:
// 静态工厂方法,根据类型创建角色实例
static std::unique_ptr<Character> Create(const std::string& name, CharacterType type)
{
switch (type)
{
case CharacterType::Warrior: return std::make_unique<Warrior>(name);
case CharacterType::Mage: return std::make_unique<Mage>(name);
case CharacterType::Monk: return std::make_unique<Monk>(name);
default: throw std::invalid_argument("Invalid character type");
}
}
};
显而易见,如果未来新增角色,比如术士,牧师等,要添加相应的类,枚举,以及新的case;会比较麻烦并且违背了开闭原则。
工厂方法模式
cpp
// 抽象工厂接口
class CharacterFactory
{
public:
virtual ~CharacterFactory() = default;
virtual std::unique_ptr<Character> CreateCharacter(const std::string& name) const = 0;
// 真正的接口:创建角色并进行初始化
std::unique_ptr<Character> CreateCharacterWithSetup(const std::string& name)
{
// 利用继承和多态的特性,在创建角色后进行初始化操作
auto character = CreateCharacter(name);
SetupCharacter(character.get());
return character;
}
protected:
// 通用初始化流程
virtual void SetupCharacter(Character& character)
{
std::cout<<"角色 "<< character.GetName() << " 已创建" << std::endl;
}
};
// 具体工厂类,根据类型创建角色实例
class WarriorFactory : public CharacterFactory
{
public:
virtual std::unique_ptr<Character> CreateCharacter(const std::string& name) const override
{
return std::make_unique<Warrior>(name);
}
protected:
virtual void SetupCharacter(Character& character) override
{
CharacterFactory::SetupCharacter(character);
std::cout<<"战士 "<< character.GetName() << " 已初始化" << std::endl; // 战士的初始化
std::cout<<"初始装备为长剑和盾牌\n";
}
};
class MageFactory : public CharacterFactory
{
public:
virtual std::unique_ptr<Character> CreateCharacter(const std::string& name) const override
{
return std::make_unique<Mage>(name);
}
protected:
virtual void SetupCharacter(Character& character) override
{
CharacterFactory::SetupCharacter(character);
std::cout<<"法师 "<< character.GetName() << " 已初始化" << std::endl; // 法师的初始化
std::cout<<"初始装备为法杖\n";
}
};
class MonkFactory : public CharacterFactory
{
public:
virtual std::unique_ptr<Character> CreateCharacter(const std::string& name) const override
{
return std::make_unique<Monk>(name);
}
protected:
virtual void SetupCharacter(Character& character) override
{
CharacterFactory::SetupCharacter(character);
std::cout<<"武僧 "<< character.GetName() << " 已初始化" << std::endl; // 武僧的初始化
std::cout<<"初始装备为禅杖\n";
}
};
当每个角色需要修改时,不会影响到其他角色。如果需要增加新的角色,只需要添加一个新的工厂类即可。
还有如果角色的创建还依赖于其他参数,比如装备,种族等,那么工厂方法会显得难以完成。这时候就需要抽象工厂,创建一系列家族产品。
抽象工厂
cpp
// 抽象基类
class Equipment
{
public:
virtual ~Equipment() = default;
virtual std::string GetDescription() const = 0;
};
// 具体装备类
class HumanSword : public Equipment
{
public:
std::string GetDescription() const override
{
return "人类专属武器-长剑";
}
};
class HumanShield : public Equipment
{
public:
std::string GetDescription() const override
{
return "人类专属-盾牌";
}
};
class ElfSword : public Equipment
{
public:
std::string GetDescription() const override
{
return "精灵专属武器-短剑";
}
};
class ElfShield : public Equipment
{
public:
std::string GetDescription() const override
{
return "精灵专属-魔法盾";
}
};
class PandEquip : public Equipment
{
public:
std::string GetDescription() const override
{
return "熊猫人专属武器-禅杖";
}
};
class PandaShield : public Equipment
{
public:
std::string GetDescription() const override
{
return "";
}
};
// 抽象工厂,种族工厂
class RaceFactory
{
public:
virtual ~RaceFactory() = default;
virtual std::unique_ptr<Character> CreateWarrior(const std::string& name) const = 0;
virtual std::unique_ptr<Character> CreateMage(const std::string& name) const = 0;
virtual std::unique_ptr<Character> CreateMonk(const std::string& name) const = 0;
virtual std::unique_ptr<Equipment> CreateWeapon() const = 0;
virtual std::unique_ptr<Equipment> CreateShield() const = 0;
virtual std::string GetRaceName() const = 0;
};
// 具体种族角色类
class HumanWarrior : public Warrior
{
public:
HumanWarrior(const std::string& name) : Warrior(name + "(人族)") {}
void PrintInfo() const override
{
std::cout << "=========人类战士=========\n";
Character::PrintInfo();
std::cout << "特长:均衡发展,适应力量" << std::endl;
}
};
class ElfMage : public Mage
{
public:
ElfMage(const std::string& name) : Mage(name + "(精灵)") {}
void PrintInfo() const override
{
std::cout << "=========精灵法师=========\n";
Character::PrintInfo();
std::cout << "特长:智力过人,魔力充足" << std::endl;
}
};
class PandaMonk : public Monk
{
public:
PandaMonk(const std::string& name) : Monk(name + "(熊猫人)") {}
void PrintInfo() const override
{
std::cout << "=========熊猫人武僧=========\n";
Character::PrintInfo();
std::cout << "特长:爱好和平" << std::endl;
}
};
// 具体工厂类
class HumanRaceFactory : public RaceFactory
{
public:
std::unique_ptr<Character> CreateWarrior(const std::string& name) const override
{
return std::make_unique<HumanWarrior>(name);
}
std::unique_ptr<Character> CreateMage(const std::string& name) const override
{
return std::make_unique<ElfMage>(name);
}
std::unique_ptr<Character> CreateMonk(const std::string& name) const override
{
return std::make_unique<PandaMonk>(name);
}
std::unique_ptr<Equipment> CreateWeapon() const override
{
return std::make_unique<HumanSword>();
}
std::unique_ptr<Equipment> CreateShield() const override
{
return std::make_unique<HumanShield>();
}
std::string GetRaceName() const override
{
return "人类";
}
};
class ElfRaceFactory : public RaceFactory
{
public:
std::unique_ptr<Character> CreateWarrior(const std::string& name) const override
{
return std::make_unique<HumanWarrior>(name);
}
std::unique_ptr<Character> CreateMage(const std::string& name) const override
{
return std::make_unique<ElfMage>(name);
}
std::unique_ptr<Character> CreateMonk(const std::string& name) const override
{
return std::make_unique<PandaMonk>(name);
}
std::unique_ptr<Equipment> CreateWeapon() const override
{
return std::make_unique<ElfSword>();
}
std::unique_ptr<Equipment> CreateShield() const override
{
return std::make_unique<ElfShield>();
}
std::string GetRaceName() const override
{
return "精灵";
}
};
class PandaRaceFactory : public RaceFactory
{
public:
std::unique_ptr<Character> CreateWarrior(const std::string& name) const override
{
return std::make_unique<HumanWarrior>(name);
}
std::unique_ptr<Character> CreateMage(const std::string& name) const override
{
return std::make_unique<ElfMage>(name);
}
std::unique_ptr<Character> CreateMonk(const std::string& name) const override
{
return std::make_unique<PandaMonk>(name);
}
std::unique_ptr<Equipment> CreateWeapon() const override
{
return std::make_unique<PandEquip>();
}
std::unique_ptr<Equipment> CreateShield()const override
{
return std::make_unique<PandaShield>();
}
std::string GetRaceName() const override
{
return "熊猫人";
}
};
最后,使用这些工厂和角色:
cpp
int main()
{
std::cout<<"============简单工厂模式示例===========\n";
auto SimpleWarrior = SimpleFactory::CreateCharacter(CharacterType::WARRIOR, "战士-小吼");
std::cout<<"创建结果: "<< SimpleWarrior->GetName() << std::endl;
std::cout<<"=============工厂方法==============\n";
auto methFactory = std::make_unique<MajorFactory>();
auto methMajor = methFactory->CreateCharacterWithSetup("法师-雅典娜");
std::cout<<"创建结果: "<< methMajor->GetName() << std::endl;
std::cout<<"==============抽象工厂模式==============\n";
auto abstractFactory = std::make_unique<PandaRaceFactory>();
auto abstractMonk = abstractFactory->CreateMonk("武僧-熊猫酒仙");
auto abstractWeapon = abstractFactory->CreateWeapon();
std::cout<<"创建结果: "<< abstractMonk->GetName() <<" + "<< abstractWeapon->GetDescription() << std::endl;
return 0;
}

工厂模式的对比:
| 简单工厂 | 工厂方法 | 抽象工厂 | |
|---|---|---|---|
| 核心思想 | 一个工厂类,根据参数创建不同产品 | 将创建延迟到子类,每个子类创建一种产品 | 创建相关产品家族,保证产品兼容性 |
| 创建目标 | 单一产品 | 单个产品系列中的具体产品 | 相关或依赖的产品家族 |
| 扩展性 | 差(增加新产品需修改工厂类) | 好(新增产品只需添加子类,无需改动原有代码) | 非常好(新增系列产品只需添加新工厂和对应的产品实现) |
| 开闭原则 | 违背(修改工厂类) | 遵循(新增子类不修改原有代码) | 遵循(新增产品家族只需添加新工厂和实现,无需改动现有代码) |
| 复杂度 | 低 | 中(引入了抽象层,增加了复杂性) | 高(需要维护多个工厂和产品类) |
| 适用场景 | 产品类型固定,变化少 | 产品类型可能频繁增加 | 需要保证产品兼容性,创建相关产品组 |