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*:创建具体类型的怪物。
优点和缺点
  • 优点
    • 通过工厂方法实现了对产品创建的封装,符合开闭原则,便于扩展。
    • 客户端代码不需要知道具体的产品类,只需依赖于产品接口。
  • 缺点
    • 增加新产品时,需要创建新的具体工厂类,可能导致类的数量增加。
    • 由于每种产品都需要一个具体工厂,可能会引入额外的复杂性。
适用场景
  • 当一个类不知道它所需要的对象的具体类型时。
  • 当一个类希望由子类来指定所创建的对象时。
  • 当需要在运行时决定创建哪个产品时。
优点和缺点
  • 优点
    • 通过工厂方法实现了对产品创建的封装,符合开闭原则,便于扩展。
    • 客户端代码不需要知道具体的产品类,只需依赖于产品接口。
  • 缺点
    • 增加新产品时,需要创建新的具体工厂类,可能导致类的数量增加。
    • 由于每种产品都需要一个具体工厂,可能会引入额外的复杂性。
适用场景
  • 当一个类不知道它所需要的对象的具体类型时。
  • 当一个类希望由子类来指定所创建的对象时。
  • 当需要在运行时决定创建哪个产品时。
相关推荐
煤泥做不到的!1 小时前
挑战一个月基本掌握C++(第十一天)进阶文件,异常处理,动态内存
开发语言·c++
F-2H1 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
axxy20001 小时前
leetcode之hot100---24两两交换链表中的节点(C++)
c++·leetcode·链表
若亦_Royi2 小时前
C++ 的大括号的用法合集
开发语言·c++
ragnwang6 小时前
C++ Eigen常见的高级用法 [学习笔记]
c++·笔记·学习
lqqjuly9 小时前
特殊的“Undefined Reference xxx“编译错误
c语言·c++
冰红茶兑滴水9 小时前
云备份项目--工具类编写
linux·c++
刘好念9 小时前
[OpenGL]使用 Compute Shader 实现矩阵点乘
c++·计算机图形学·opengl·glsl
酒鬼猿10 小时前
C++进阶(二)--面向对象--继承
java·开发语言·c++
姚先生9710 小时前
LeetCode 209. 长度最小的子数组 (C++实现)
c++·算法·leetcode