欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > C++ 设计模式——工厂方法模式

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

2024/10/23 20:29:00 来源:https://blog.csdn.net/qq_68194402/article/details/141228081  浏览:    关键词:C++ 设计模式——工厂方法模式

工厂方法模式

      • 工厂方法模式
        • 主要组成部分
        • 代码实现
        • 工厂方法模式模式的 UML 图
        • 工厂方法模式 UML 图解析
        • 优点和缺点
        • 适用场景

工厂方法模式

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

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

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

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

#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 图

工厂方法模式 UML 图解析
  • 类关系
    • Monster:抽象基类,定义了怪物的基本属性(如 m_lifem_magicm_attack)。
    • M_UndeadM_ElementM_Mechanic:具体类,继承自 Monster,实现不同类型的怪物。
  • 工厂类
    • M_ParFactory:抽象工厂类,定义了创建怪物的接口 createMonster
    • M_UndeadFactoryM_ElementFactoryM_MechanicFactory:具体工厂类,继承自 M_ParFactory,分别负责创建不同类型的怪物。
    • M_ChildFactory:模板工厂类,能够创建任意类型的怪物,提供更灵活的创建方式。
  • 稳定部分
    • Gbl_CreateMonster 函数依赖的 Monster 类和 M_ParFactory 类属于稳定部分,不需要更改。
  • 变化部分
    • M_UndeadFactoryM_ElementFactoryM_MechanicFactory 类以及具体怪物类(如 M_UndeadM_Mechanic)属于变化部分。Gbl_CreateMonster 函数不依赖于这些变化部分。
  • 扩展新类型
    • 当需要引入新怪物类型(例如 M_Beast)时,无需更改 Gbl_CreateMonster 函数或修改 MonsterFactorycreateMonster 方法。只需创建一个继承自 Monster 的新类 M_Beast 和一个继承自 M_ParFactory 的新工厂类 M_BeastFactory,这符合开闭原则:对扩展开放,对修改关闭。
  • 隐藏实现细节
    • 如果 M_ParFactory 及其子类由第三方开发,工厂方法模式可以有效隐藏具体怪物类(如 M_UndeadM_ElementM_Mechanic),避免暴露给开发者。
  • 接口扩展
    • M_ParFactory 的接口可以根据需要扩展,例如增加对 NPC(非玩家角色,如商人、路人等)的创建支持,或为 createMonster 提供默认实现。
  • 增加工厂类的代价
    • 增加新的工厂类是工厂方法模式的必然代价,但这为系统的灵活性和可扩展性提供了保障。
优点和缺点
  • 优点
    • 符合开闭原则:新增产品时,只需创建新的产品类和相应的工厂类,无需修改现有代码。
    • 减少耦合:客户端代码与具体产品类解耦,依赖于抽象工厂接口,增强了系统的灵活性。
    • 扩展性强:可以方便地扩展新的产品类型,适合复杂系统的需求变化。
    • 提高代码可读性:通过明确的工厂类和产品类的分离,代码结构更加清晰。
  • 缺点
    • 类的数量增加:每新增一种产品都需要创建相应的工厂类,可能导致类的数量剧增,增加系统复杂性。
    • 实现复杂性:对于简单产品的创建,工厂方法模式可能显得过于复杂,增加不必要的开销。
    • 难以管理:如果产品种类过多,可能导致工厂类的管理变得困难。
适用场景
  • 产品族:需要创建一系列相关或相互依赖的对象时,工厂方法模式非常适合。
  • 产品类型变化频繁:当产品类型经常变化,且需要动态地扩展新产品时,工厂方法模式提供了良好的灵活性。
  • 需要解耦的系统:当系统需要将对象创建与使用分离时,工厂方法模式可以有效降低耦合度。
  • 复杂对象的创建:当对象的创建过程复杂,且可能涉及多个步骤时,工厂方法模式可以封装这些复杂性。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com