动态工厂模式的实现

本文介绍了在项目开发中,如何通过动态工厂模式解决随着类型增多导致的`switch`语句冗长的问题,通过预先注册键值对(类名和构造函数),在需要时通过键获取构造函数创建对象。
摘要由CSDN通过智能技术生成

        常用项目中,工厂模式通常会采用swith的方式进行创建,随着类型的不断增加,就会疯狂增加switch的case项,为了解决这个问题,采用动态注册的方式实现工厂实例的创建。实现思路上,通过提前注册key和构造器,然后在需要创建的地方通过key来找到构造器从何构造出目标对象。代码如下:

/********************************************************************************
 * Copyright(c) 2023-2030 All rights reserved.
 * - Filename
 * - Author  Vincent
 * - Version V1.0.0
 * - Date    2024/02/11
 * - Brief
 * - FunctionList:
 ******************************************************************************
 * History:
 *
 *
 *
 ******************************************************************************
 */

#pragma once

#include <map>
#include <memory>
#include <functional>
#include "factory.hpp"
namespace factory
{
    class DynamicFactory
    {
    public:
        template <typename T>
        struct Register
        {
            /// @brief 注册不带参的类构造函数
            /// @param name  类名称
            inline Register(const std::string &name)
            {
                DynamicFactory::get()._factoryMap.emplace(name, []
                                                          { return new T(); });
            }
            /// @brief 注册带参的类构造函数
            /// @param name  类名称
            template <typename... Args>
            inline Register(const std::string &name, Args... args)
            {
                DynamicFactory::get()._factoryMap.emplace(name, [&]
                                                          { return new T(args...); });
            }
        };
        /// @brief 返回具体的类指针,这里采用dynamic_pointer_cast进行基类指针转换到派生指针。
        /// @param name  类名称
        /// @return 
        template <typename DeriveClass, typename T = DeriveClass>
        inline std::shared_ptr<T> produce_shared_ptr(const std::string &name)
        {
            if (_factoryMap.find(name) == _factoryMap.end())
                throw std::invalid_argument("the service_id is not exist!");
            return std::dynamic_pointer_cast<T>(std::shared_ptr<BaseFactory>(_factoryMap[name]()));
        }
        /// @brief 动态工厂的单例
        /// @return 动态
        inline static DynamicFactory &get()
        {
            static DynamicFactory instance;
            return instance;
        }

    private:
        DynamicFactory(){};
        DynamicFactory(const DynamicFactory &) = delete;
        DynamicFactory(DynamicFactory &&) = delete;
        std::map<std::string, std::function<BaseFactory *()>> _factoryMap;
    };
};
#define REGISTER_FACTORY_WITH_PARAM(T, name, ...) static factory::DynamicFactory::Register<T>(factory_##T##_)(name, ##__VA_ARGS__);

使用方法:

#include "DynamicFactory.hpp"
#include "factory1.hpp"
#include "factory2.hpp"
#include <iostream>

#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <thread>
#include <chrono>
bool isExit = false;
void signal_hander_fun(int signum)
{
    isExit = true;
    printf("catch signal %d\n", signum);
}

int main(int argc, char *argv[])
{
    signal(SIGINT, signal_hander_fun);

    REGISTER_FACTORY_WITH_PARAM(Factory1, "factory1");
    REGISTER_FACTORY_WITH_PARAM(Factory2, "factory2");
    auto factory1 = factory::DynamicFactory::get().produce_shared_ptr<Factory1>("factory1");
    factory1->printf();
    auto factory2 = factory::DynamicFactory::get().produce_shared_ptr<Factory2>("factory2");
    factory2->printf();

    while (!isExit)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    return 0;
}

运行:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值