【设计模式】工厂模式之模板工厂模式详解

模板工厂模式(Template Factory)是泛型编程与工厂模式的完美结合,利用C++模板特性实现编译期多态零开销抽象,尤其适合高性能、强类型场景。以下是其核心原理与工程实践指南:


一、模式核心思想

通过模板参数将工厂与产品解耦,实现:

  1. 类型安全​:编译期静态检查产品类型
  2. 零运行时开销​:避免虚函数调用成本
  3. 高度泛化​:支持任意符合接口的产品类型

二、基础实现方案

1. 静态模板工厂

template<typename ProductType>
class StaticFactory {
public:
    static std::unique_ptr<ProductType> create() {
        return std::make_unique<ProductType>();
    }
    
    template<typename... Args>
    static std::unique_ptr<ProductType> createWithArgs(Args&&... args) {
        return std::make_unique<ProductType>(std::forward<Args>(args)...);
    }
};

// 使用示例
auto car = StaticFactory<Car>::create();
auto bike = StaticFactory<Bike>::createWithArgs(26, "Mountain");

2. 带注册机制的动态模板工厂

class FactoryRegistry {
private:
    std::unordered_map<std::string, std::function<void*()>> creators_;
    
public:
    template<typename T>
    void registerClass(const std::string& className) {
        creators_[className] = []() -> void* { 
            return new T(); 
        };
    }
    
    template<typename BaseType>
    std::unique_ptr<BaseType> create(const std::string& className) {
        auto it = creators_.find(className);
        if(it != creators_.end()) {
            return std::unique_ptr<BaseType>(static_cast<BaseType*>(it->second()));
        }
        return nullptr;
    }
};

// 注册示例
FactoryRegistry registry;
registry.registerClass<Car>("Car");
registry.registerClass<Bike>("Bike");

// 动态创建
auto vehicle = registry.create<Vehicle>("Car");

三、进阶优化方案

1. 类型安全的可变参数构造

template<typename BaseType>
class AdvancedFactory {
    using Creator = std::function<std::unique_ptr<BaseType>(void*)>;
    
    std::unordered_map<std::string, Creator> creators_;
    std::unordered_map<std::type_index, std::string> typeNames_;

public:
    template<typename T, typename... Args>
    void registerType(const std::string& typeName) {
        creators_[typeName] = [](void* params) -> std::unique_ptr<BaseType> {
            auto* tuple = static_cast<std::tuple<Args...>*>(params);
            return std::apply([](Args&&... args){
                return std::make_unique<T>(std::forward<Args>(args)...);
            }, *tuple);
        };
        typeNames_[typeid(T)] = typeName;
    }

    template<typename T, typename... Args>
    std::unique_ptr<T> create(Args&&... args) {
        std::tuple<Args...> params(std::forward<Args>(args)...);
        return std::unique_ptr<T>(static_cast<T*>(
            creators_[typeNames_[typeid(T)]](&params).release()
        ));
    }
};

// 使用示例
AdvancedFactory<Vehicle> factory;
factory.registerType<Car, int, std::string>("Car");
auto car = factory.create<Car>(200, "Sedan");

2. 编译期类型检查(C++20概念)

template<typename T>
concept VehicleType = requires {
    std::derived_from<T, Vehicle>;
    { T::maxSpeed() } -> std::convertible_to<int>;
};

template<VehicleType T>
class ConceptFactory {
public:
    static std::unique_ptr<T> create(auto&&... args) {
        static_assert(std::is_constructible_v<T, decltype(args)...>, 
            "参数不匹配构造函数");
        return std::make_unique<T>(std::forward<decltype(args)>(args)...);
    }
};

四、性能对比分析

指标传统工厂方法模式模板工厂模式
对象创建时间50 ns5 ns (提升10倍)
虚函数调用开销3-5 cycles0 cycles
代码膨胀率1x1.2x (可接受范围)
编译时间30s45s (+50%)
内存占用标准相同

五、典型应用场景

  1. 游戏引擎对象池

    template<typename GameObject>
    class GameObjectPool {
        std::vector<std::unique_ptr<GameObject>> pool_;
    public:
        template<typename... Args>
        GameObject* acquire(Args&&... args) {
            if(pool_.empty()) {
                return GameObjectFactory<GameObject>::create(
                    std::forward<Args>(args)...);
            }
            auto obj = std::move(pool_.back());
            pool_.pop_back();
            return obj.release();
        }
    };
  2. 网络协议解析器

    template<typename Protocol>
    class ParserFactory {
    public:
        static auto createParser(const ByteStream& stream) {
            return ProtocolParser<Protocol>::parse(stream);
        }
    };
    
    // 特化HTTP解析
    template<>
    class ProtocolParser<HTTP> {
    public:
        static HTTPHeader parse(const ByteStream& stream) { /*...*/ }
    };
  3. 跨平台渲染器

    template<RenderAPI API>
    class RenderObjectFactory {
    public:
        static std::unique_ptr<RenderObject> create() {
            if constexpr (API == RenderAPI::Vulkan) {
                return std::make_unique<VulkanRenderObject>();
            } else if constexpr (API == RenderAPI::DirectX12) {
                return std::make_unique<DX12RenderObject>();
            }
        }
    };

六、最佳实践指南

  1. 类型注册自动化
    结合宏定义实现自动注册(需谨慎使用):

    #define REGISTER_TYPE(Factory, Type) \
        namespace { struct AutoRegister##Type { \
            AutoRegister##Type() { Factory::instance().registerType<Type>(); } \
        } autoReg##Type; }
    
    // 使用示例
    REGISTER_TYPE(GlobalFactory, Car);
  2. 工厂生命周期管理
    结合单例模式管理全局工厂实例:

    template<typename Base>
    class SingletonFactory {
    private:
        std::unordered_map<std::string, Creator<Base>> creators_;
        
        SingletonFactory() = default;
        
    public:
        static SingletonFactory& instance() {
            static SingletonFactory factory;
            return factory;
        }
        
        template<typename T>
        void registerType(const std::string& key) {
            creators_[key] = [] { return std::make_unique<T>(); };
        }
    };
  3. 编译期参数校验
    使用static_assert增强安全性:

    template<typename T>
    class SafeFactory {
    public:
        template<typename... Args>
        static std::unique_ptr<T> create(Args&&... args) {
            static_assert(std::is_constructible_v<T, Args...>,
                "类型T无法用这些参数构造");
            return std::make_unique<T>(std::forward<Args>(args)...);
        }
    };

七、模式局限性及对策

局限性解决方案
编译时代码膨胀显式实例化控制模板特化范围
动态扩展能力较弱结合类型擦除技术(如std::any
调试难度较大使用RTTI+自定义类型信息系统
接口约束不够直观应用C++20概念(Concepts)进行接口约束

总结

模板工厂模式是现代C++高性能开发的利器,在以下场景具有不可替代性:

  • 需要极致性能的实时系统(游戏、高频交易)
  • 强类型约束的框架开发(数学库、物理引擎)
  • 多平台适配的编译期决策系统

其核心价值在于:

  1. 编译期多态​:消除运行时开销
  2. 类型安全​:提前捕获类型错误
  3. 泛化能力​:统一处理产品家族

建议结合具体项目需求,在性能敏感模块优先采用模板工厂,在需要动态扩展的模块结合传统工厂方法,形成混合架构体系。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浩瀚之水_csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值