C++ 设计模式——工厂方法模式

工厂方法模式

工厂方法模式

工厂方法模式是一种创建型设计模式,它通过定义一个接口用于创建对象,但由子类决定实例化哪个类。与简单工厂模式不同,工厂方法模式将对象的创建委托给子类,从而实现更好的扩展性和灵活性。

引入"工厂方法模式(实现意图):定义一个用于创建对象的接口,但由子类决定要实例化的类是哪一个。该模式使得某个类的实例化延迟到子类。

主要组成部分
  • 产品接口(Product):定义了工厂方法所创建的对象的接口。
  • 具体产品(ConcreteProduct):实现了产品接口的具体类。
  • 工厂接口(Creator):声明了工厂方法,返回一个产品对象。
  • 具体工厂(ConcreteCreator):实现了工厂接口,返回具体产品的实例。
代码实现

以下代码,主要用工厂方法模式创建不同类型的怪物对象:

c++ 复制代码
#include <iostream>
#include <string>

using namespace std;

// 怪物父类
class Monster
{
public:
    Monster(int life, int magic, int attack) : m_life(life), m_magic(magic), m_attack(attack) {}
    virtual ~Monster() {} // 虚析构函数

protected:
    int m_life;    // 生命值
    int m_magic;   // 魔法值
    int m_attack;  // 攻击力
};

// 亡灵类怪物
class M_Undead : public Monster
{
public:
    M_Undead(int life, int magic, int attack) : Monster(life, magic, attack)
    {
        cout << "一只亡灵类怪物来到了这个世界" << endl;
    }
    // 其他代码略....
};

// 元素类怪物
class M_Element : public Monster
{
public:
    M_Element(int life, int magic, int attack) : Monster(life, magic, attack)
    {
        cout << "一只元素类怪物来到了这个世界" << endl;
    }
    // 其他代码略....
};

// 机械类怪物
class M_Mechanic : public Monster
{
public:
    M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack)
    {
        cout << "一只机械类怪物来到了这个世界" << endl;
    }
    // 其他代码略....
};

// 工厂方法模式
// 所有工厂类的父类
class M_ParFactory
{
public:
    virtual Monster* createMonster() = 0; // 纯虚函数
    virtual ~M_ParFactory() {} // 虚析构函数
};

// 亡灵类怪物工厂
class M_UndeadFactory : public M_ParFactory
{
public:
    virtual Monster* createMonster()
    {
        return new M_Undead(300, 50, 80); // 创建亡灵类怪物
    }
};

// 元素类怪物工厂
class M_ElementFactory : public M_ParFactory
{
public:
    virtual Monster* createMonster()
    {
        return new M_Element(200, 80, 100); // 创建元素类怪物
    }
};

// 机械类怪物工厂
class M_MechanicFactory : public M_ParFactory
{
public:
    virtual Monster* createMonster()
    {
        return new M_Mechanic(400, 0, 110); // 创建机械类怪物
    }
};

// 全局创建怪物对象的函数
Monster* Gbl_CreateMonster(M_ParFactory* factory)
{
    return factory->createMonster(); // 根据工厂创建怪物
}

// 创建怪物工厂子类模板
template <typename T>
class M_ChildFactory : public M_ParFactory
{
public:
    virtual Monster* createMonster() {
        return new T(300, 50, 80); // 创建具体类型的怪物
    }
};

// 使用示例
int main()
{
    // 使用具体工厂创建怪物
    M_ParFactory* undeadFactory = new M_UndeadFactory();
    Monster* undead = Gbl_CreateMonster(undeadFactory);
    delete undead; // 释放内存
    delete undeadFactory;

    M_ParFactory* elementFactory = new M_ElementFactory();
    Monster* element = Gbl_CreateMonster(elementFactory);
    delete element; // 释放内存
    delete elementFactory;

    M_ParFactory* mechanicFactory = new M_MechanicFactory();
    Monster* mechanic = Gbl_CreateMonster(mechanicFactory);
    delete mechanic; // 释放内存
    delete mechanicFactory;

    // 使用模板工厂创建怪物
    M_ChildFactory<M_Undead> undeadChildFactory;
    Monster* undeadChild = Gbl_CreateMonster(&undeadChildFactory);
    delete undeadChild; // 释放内存

    return 0;
}
工厂方法模式模式的 UML 图
UML图解析
  • 类关系:
    • Monster 为抽象基类,定义了怪物的基本属性(m_lifem_magicm_attack)。
    • M_UndeadM_ElementM_Mechanic 类继承自 Monster,实现不同类型的怪物。
  • 工厂类:
    • M_ParFactory 类为抽象工厂类,定义了创建怪物的接口 createMonster
    • M_UndeadFactoryM_ElementFactoryM_MechanicFactory 类继承自 M_ParFactory,分别创建不同类型的怪物。
    • M_ChildFactory 类为模板工厂,能够创建任意类型的怪物。
类与方法
  1. 产品类
    • Monster(抽象类)
      • 属性:
        • # m_life:生命值,使用 # 表示为保护属性,子类可以访问。
        • # m_magic:魔法值,使用 # 表示为保护属性。
        • # m_attack:攻击力,使用 # 表示为保护属性。
      • 方法:
        • + Monster(int life, int magic, int attack):构造函数,公开方法。
        • - ~Monster():析构函数,私有方法。
    • M_UndeadM_ElementM_Mechanic(具体类)
      • 方法:
        • + M_Undead(int life, int magic, int attack):构造函数
        • + M_Element(int life, int magic, int attack):构造函数
        • + M_Mechanic(int life, int magic, int attack):构造函数
  2. 工厂类
    • M_ParFactory(抽象工厂类)
      • 方法:
        • + createMonster() : Monster*:纯虚函数,返回一个怪物对象。
        • - ~M_ParFactory():析构函数,私有方法。
    • M_UndeadFactoryM_ElementFactoryM_MechanicFactory(具体工厂类)
      • 方法:
        • + createMonster() : Monster*:实现具体的怪物创建逻辑。
    • M_ChildFactory<T>(模板工厂)
      • 方法:
        • + createMonster() : Monster*:创建具体类型的怪物。
优点和缺点
  • 优点
    • 通过工厂方法实现了对产品创建的封装,符合开闭原则,便于扩展。
    • 客户端代码不需要知道具体的产品类,只需依赖于产品接口。
  • 缺点
    • 增加新产品时,需要创建新的具体工厂类,可能导致类的数量增加。
    • 由于每种产品都需要一个具体工厂,可能会引入额外的复杂性。
适用场景
  • 当一个类不知道它所需要的对象的具体类型时。
  • 当一个类希望由子类来指定所创建的对象时。
  • 当需要在运行时决定创建哪个产品时。
优点和缺点
  • 优点
    • 通过工厂方法实现了对产品创建的封装,符合开闭原则,便于扩展。
    • 客户端代码不需要知道具体的产品类,只需依赖于产品接口。
  • 缺点
    • 增加新产品时,需要创建新的具体工厂类,可能导致类的数量增加。
    • 由于每种产品都需要一个具体工厂,可能会引入额外的复杂性。
适用场景
  • 当一个类不知道它所需要的对象的具体类型时。
  • 当一个类希望由子类来指定所创建的对象时。
  • 当需要在运行时决定创建哪个产品时。
相关推荐
2601_956121974 小时前
二分算法(知识点+题目)
c++·算法
蒙奇·D·路飞-6 小时前
OpenClaw:开源的《合金弹头》精神续作与终极本地部署指南
c++·开源·mfc
董员外7 小时前
RAG 系统进化论(八):Agentic RAG(智能体式 RAG),从回答问题到完成任务
人工智能·后端·设计模式
小星星闪亮登场8 小时前
2026萌新联赛第三场-- (郑州轻工业大学)
数据结构·c++·经验分享·算法·贪心算法·排序算法·深度优先
梓䈑8 小时前
【用 Vibe Coding 实现的 C++17 在线判题系统】前端开发 + Web 自动化测试
前端·c++·ai编程
冻柠檬飞冰走茶8 小时前
PTA基础编程题目集 7-8超速判断(C++语言实现)
开发语言·数据结构·c++·算法
TunerT_TQ9 小时前
Valhalla 静态工程审阅 #018|MMCV 源码证据驱动评测【大厂开源基础设施特辑】
c++·开源·mfc·#计算机视觉·#商汤科技·#openmmlab·#静态源码审计
别动我齐刘海10 小时前
Day6 unitree_G1人形机器人GMR—— MotionInput
c语言·c++·人工智能·学习·机器学习·机器人·github
Henry Zhu12311 小时前
C++17 `weak_from_this` 详解:让对象安全地观察自己
c++
董员外11 小时前
RAG 系统进化论(七):Multimodal RAG(多模态 RAG),当知识存在于表格、图片和页面中
人工智能·后端·设计模式