在软件开发中,工厂方法模式是一种常用的设计模式,用于创建对象。通过使用C++11的新特性,我们可以进一步改进工厂方法模式,使其更加灵活和高效。本文将详细介绍如何使用C++11的std::function
、lambda表达式和智能指针来实现一个支持运行时配置的工厂方法模式,以创建不同类型的"勇勇"角色。
1. 核心概念
工厂方法模式:通过定义一个用于创建对象的接口,让子类决定实例化哪一个类。这样,工厂方法将对象的创建推迟到子类中。
C++11特性:
std::function
:一个通用的多态函数包装器,可以存储、复制和调用任何可调用目标。- Lambda表达式:提供了一种简洁的方式来定义匿名函数。
- 智能指针 :如
std::unique_ptr
,用于自动管理动态内存,避免内存泄漏。
2. 实现思路
我们的目标是创建一个支持运行时动态配置的工厂方法模式。具体来说,我们希望能够在程序运行时注册不同的勇勇类型创建函数,并根据需要动态地创建相应类型的勇勇实例。
3. 代码实现
cpp
#include <map>
#include <functional>
#include <memory>
#include <string>
#include <stdexcept>
#include <iostream>
// 定义勇勇类型枚举
enum class YongYongType { Common, Advanced };
// 定义勇勇接口
class YongYong {
public:
virtual ~YongYong() = default;
virtual void attack() const = 0;
virtual void defense() const = 0;
};
// 具体的勇勇实现类
class CommonYongYong : public YongYong {
public:
void attack() const override {
std::cout << "普通勇勇发起普通攻击。" << std::endl;
}
void defense() const override {
std::cout << "普通勇勇进行普通防御。" << std::endl;
}
};
class AdvancedYongYong : public YongYong {
public:
void attack() const override {
std::cout << "高级勇勇发起强力攻击。" << std::endl;
}
void defense() const override {
std::cout << "高级勇勇进行高级防御。" << std::endl;
}
};
// 工厂类
class GuoYaoFactory {
public:
using CreatorFunc = std::function<std::unique_ptr<YongYong>()>;
static void registerCreator(YongYongType type, CreatorFunc creator) {
getRegistry()[type] = creator;
}
static std::unique_ptr<YongYong> create(YongYongType type) {
auto it = getRegistry().find(type);
if (it != getRegistry().end()) {
return it->second();
}
throw std::invalid_argument("Unknown YongYong type");
}
private:
static std::map<YongYongType, CreatorFunc>& getRegistry() {
static std::map<YongYongType, CreatorFunc> registry;
return registry;
}
};
// 初始化工厂注册表
void initGuoYaoFactory() {
GuoYaoFactory::registerCreator(YongYongType::Common, []() {
return std::make_unique<CommonYongYong>();
});
GuoYaoFactory::registerCreator(YongYongType::Advanced, []() {
return std::make_unique<AdvancedYongYong>();
});
}
int main() {
initGuoYaoFactory();
// 创建不同类型的勇勇对象
auto commonYongYong = GuoYaoFactory::create(YongYongType::Common);
commonYongYong->attack();
commonYongYong->defense();
auto advancedYongYong = GuoYaoFactory::create(YongYongType::Advanced);
advancedYongYong->attack();
advancedYongYong->defense();
return 0;
}
4. 代码解释
-
枚举类型YongYongType:
- 定义了两种勇勇类型:Common(普通勇勇)和Advanced(高级勇勇)。
-
接口YongYong:
- 定义了勇勇类的接口,包含两个纯虚函数
attack
和defense
,分别表示攻击和防御行为。
- 定义了勇勇类的接口,包含两个纯虚函数
-
具体勇勇实现类:
CommonYongYong
实现了普通勇勇的攻击和防御行为,输出相应的信息。AdvancedYongYong
实现了高级勇勇的攻击和防御行为,输出相应的信息。
-
工厂类GuoYaoFactory:
- 使用
std::function
定义了创建函数的类型CreatorFunc
。 registerCreator
方法用于注册具体的勇勇类型创建函数。create
方法根据给定的勇勇类型查找并调用对应的创建函数,返回勇勇对象的唯一指针。getRegistry
方法返回一个静态的std::map
,用于存储勇勇类型的创建函数映射。
- 使用
-
初始化函数initGuoYaoFactory:
- 在程序启动时调用,注册所有已知的勇勇类型的创建函数。这里使用了lambda表达式来简化创建函数的定义。
-
main函数:
- 初始化工厂注册表。
- 使用工厂类创建不同类型的勇勇对象,并调用它们的攻击和防御方法,以展示工厂方法模式的效果。
5. 优点
- 动态扩展:通过注册表机制,可以在运行时动态地添加新的勇勇类型,而无需修改工厂类的代码。
- 简洁性 :使用lambda表达式和
std::function
简化了创建函数的定义和管理。 - 内存安全 :使用
std::unique_ptr
管理对象的生命周期,避免了手动内存管理带来的潜在问题。 - 灵活性:支持多种创建方式,可以根据需求灵活地选择不同的创建函数。
6. 总结
通过使用C++11的特性,我们可以显著改进工厂方法模式的实现。std::function
和lambda表达式使得创建函数的定义更加简洁和灵活,而智能指针则确保了内存的安全管理。此外,通过静态注册表的设计,我们实现了运行时动态配置的能力,使系统更加灵活和可扩展。这种改进不仅提高了代码的可读性和维护性,还为系统的未来发展预留了充足的空间。通过这种方式,我们可以设计出更加灵活和可扩展的系统,从而更好地应对需求的变化和扩展。
Horse3D游戏引擎研发笔记(一):从使用Qt的OpenGL库绘制三角形开始
Horse3D游戏引擎研发笔记(二):基于QtOpenGL使用仿Three.js的BufferAttribute结构重构三角形绘制
Horse3D游戏引擎研发笔记(三):使用QtOpenGL的Shader编程绘制彩色三角形
Horse3D游戏引擎研发笔记(四):在QtOpenGL下仿three.js,封装EBO绘制四边形
Horse3D游戏引擎研发笔记(五):在QtOpenGL环境下,仿three.js的BufferGeometry管理VAO和EBO绘制四边形
Horse3D游戏引擎研发笔记(六):在QtOpenGL环境下,仿Unity的材质管理Shader绘制四边形
Horse3D游戏引擎研发笔记(七):在QtOpenGL环境下,使用改进的Uniform变量管理方式绘制多彩四边形 (相较于Unity、Unreal Engine与Godot引擎)