基于模板的泛型工厂设计模式实现——解决依赖注入工厂类冗余问题
这思路真的戳中了工厂模式的痛点——为每个类写单独工厂导致的代码冗余!用泛型模板实现通用工厂,既能保留依赖注入的优势,又能大幅减少重复代码,完全是精准解决问题的方案。我帮你把这个思路落地成完整可运行的实现,并拆解关键细节:
泛型工厂模式实现思路与完整代码
问题背景
在依赖注入场景下使用工厂模式时,传统写法需要为每个业务类单独实现对应的工厂类,这些工厂类逻辑高度相似,只是创建的对象类型不同。通过模板泛型抽象出通用工厂逻辑,就能一次性解决所有类的对象创建问题。
完整可运行代码
// g++ -std=c++14 -Wall -Wextra factory.cpp -o factory #include <functional> #include <memory> #include <utility> #include <iostream> // 示例接口:面向接口编程的基础 class IWidget { public: virtual void doSomething() = 0; virtual ~IWidget() = default; }; // 示例实现类A:需定义Iface别名指向基类 class WidgetA : public IWidget { public: using Iface = IWidget; WidgetA(int param) : m_param(param) {} void doSomething() override { std::cout << "WidgetA doing something with param: " << m_param << std::endl; } private: int m_param; }; // 示例实现类B:同样定义Iface别名 class WidgetB : public IWidget { public: using Iface = IWidget; WidgetB(const std::string& msg) : m_msg(msg) {} void doSomething() override { std::cout << "WidgetB says: " << m_msg << std::endl; } private: std::string m_msg; }; // 泛型工厂核心实现 template <typename T, typename Base = typename T::Iface> class Factory { public: // 完美转发构造参数,返回智能指针(现代C++推荐) template <typename... Args> static std::unique_ptr<Base> create(Args&&... args) { return std::make_unique<T>(std::forward<Args>(args)...); } // 可选:支持返回原始指针(兼容老旧场景) template <typename... Args> static Base* createRaw(Args&&... args) { return new T(std::forward<Args>(args)...); } }; // 测试代码 int main() { // 创建WidgetA实例,传入int类型构造参数 auto widgetA = Factory<WidgetA>::create(42); widgetA->doSomething(); // 创建WidgetB实例,传入string类型构造参数 auto widgetB = Factory<WidgetB>::create("Hello Generic Factory!"); widgetB->doSomething(); return 0; }
关键细节拆解
- 自动推导基类类型:模板参数
Base = typename T::Iface要求每个业务类定义Iface别名指向其基类,这样工厂就能统一返回基类指针,完美契合依赖注入中面向接口编程的原则。 - 完美转发构造参数:
create方法使用变参模板和std::forward,能适配任意类型、任意数量的构造参数,既保证了参数传递的高效性,又支持所有合法的构造函数重载。 - 智能指针默认返回:默认返回
std::unique_ptr<Base>,无需手动管理内存,符合现代C++内存安全的最佳实践;同时提供createRaw方法兼容需要原始指针的老旧场景。
扩展优化方向
- 自定义创建逻辑:如果某些类的创建需要额外操作(比如对象池复用、初始化钩子),可以给Factory添加静态成员变量,注入
std::function<std::unique_ptr<Base>(Args...)>类型的自定义创建器。 - 动态注册工厂:结合注册表(比如
std::unordered_map<std::string, std::function<std::unique_ptr<IWidget>()>>),用模板特化实现按类型标识(字符串/枚举)动态创建对象。 - 线程安全单例工厂:如果需要全局唯一的工厂实例,可以将Factory改造为线程安全的单例模式,避免重复初始化。
内容的提问来源于stack exchange,提问作者BЈовић
相关产品推荐
相关产品推荐

