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 小时前
刷穿LeetCode:BFS 解决 Flood Fill 算法
数据结构·c++·算法·leetcode·职场和发展·bfs·宽度优先
楼田莉子3 小时前
Linux网络:NAT_代理
linux·运维·服务器·开发语言·c++·后端
南境十里·墨染春水3 小时前
C++日志 2——实现单线程日志系统
java·jvm·c++
zh_xuan3 小时前
api测试工具添加历史记录功能
c++·libcurl·duilib
休息一下接着来3 小时前
C++ 固定容量环形队列实现
c++·算法
Dabei4 小时前
Android 无障碍服务实现美团/微信自动化:客户端开发实践
前端·设计模式
wxin_VXbishe5 小时前
springboot新能源车充电站管理系统小程序-计算机毕业设计源码29213
java·c++·spring boot·python·spring·django·php
05候补工程师6 小时前
【408 从零到一】线性表逻辑特征、存储结构对比与 C/C++ 动态内存分配避坑指南
c语言·开发语言·数据结构·c++·考研
怕什么真理无穷7 小时前
C++面试5_ TCP 粘包2(工业级)
开发语言·c++·tcp/ip
努力努力再努力wz7 小时前
【MySQL 进阶系列】拒绝滥用root:从 mysql.user 到权限校验,带你彻底理解用户管理与授权机制!
android·c语言·开发语言·数据结构·数据库·c++·mysql