开发随笔1 - 现代C++对象工厂模式实现
这篇文章将介绍一个基于现代C++特性的对象工厂实现方案,该方案采用了模板元编程和静态注册技术,为创建对象提供了灵活且类型安全的机制。
核心设计理念
这个工厂模式实现包含三个关键组件:
- ObjectFactory模板类:通用的工厂基类,提供对象注册和创建功能
- AutoRegister辅助类:自动注册具体产品类的工具类
- REGISTER_PRODUCT宏:简化注册过程的语法糖
技术亮点
- 类型安全:通过模板参数确保产品类型匹配
- 自动注册:利用静态变量初始化实现零配置注册
- 内存管理:使用shared_ptr自动管理对象生命周期
- 单例模式:Meyer's singleton保证静态数据安全初始化
- 简洁接口:提供清晰的工厂API(register/create/clear)
代码
#include <functional> #include <map> #include <memory> template<class AbstractProduct, class ProductID = std::string> class ObjectFactory { public: using ProductPtr = std::shared_ptr<AbstractProduct>; using Builder = std::function<ProductPtr()>; static void registerBuilder(const ProductID& id, Builder builder) { getBuilders().insert_or_assign(id,builder); } template<typename ConcreteProduct,typename... Args> static void registerBuilder(const ProductID& id) { registerBuilder(id,[]() { return std::make_shared<ConcreteProduct>(); }); } static ProductPtr create(const ProductID& id) { auto it = getBuilders().find(id); return it != getBuilders().end() ? it->second() : nullptr; } static void clear() { getBuilders().clear(); } private: static std::unordered_map<ProductID, Builder>& getBuilders() { static std::unordered_map<ProductID, Builder> instance; return instance; } }; template<class AbstractProduct, class ConcreteProduct, class ProductID = std::string> class AutoRegister { public: explicit AutoRegister(const ProductID& id) { ObjectFactory<AbstractProduct,ProductID>::template registerBuilder<ConcreteProduct>(id); } }; #define REGISTER_PRODUCT(AbstractType, ConcreteType, id) \ namespace\ { \ AutoRegister<AbstractType, ConcreteType> auto_reg_##ConcreteType(id); \ }
使用方式
using namespace std; class Animal { public: virtual void say() = 0; }; class Cat : public Animal { public: Cat() { } void say() { std::cout<<"i am cat"<<std::endl; } private: }; class Dog : public Animal { public: void say() { std::cout<<"i am dog"<<std::endl; } }; REGISTER_PRODUCT(Animal, Cat,"Cat") REGISTER_PRODUCT(Animal, Dog,"Dog") int main() { auto animal1 = ObjectFactory<Animal,std::string>::create("Cat"); animal1->say(); auto animal2 = ObjectFactory<Animal,std::string>::create("Dog"); animal2->say(); return 0; }
浙公网安备 33010602011771号