工厂模式(产品注册模板类+单例工厂模板类)

Posted that-boy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工厂模式(产品注册模板类+单例工厂模板类)相关的知识,希望对你有一定的参考价值。

?? 工厂模式

产品注册模板类+单例工厂模板类

#pragma once

#ifndef _FACTORYMETHOD_H_
#define _FACTORYMETHOD_H_

#include <map>
#include <memory>
#include <string>

namespace thatboy
{
    // 基类,产品注册模板接口类
    template <class ProductType_t>
    class IProductRegistrar
    {
    public:
        virtual std::shared_ptr<ProductType_t> CreateProduct() = 0;
    protected:
        IProductRegistrar() = default;
        virtual ~IProductRegistrar() = default;
        IProductRegistrar(const IProductRegistrar&) = delete;
        IProductRegistrar& operator=(const IProductRegistrar&) = delete;
    };

    // 工厂模板类,用于获取和注册产品对象
    template <class ProductType_t>
    class ProductFactory
    {
    public:
        static ProductFactory<ProductType_t>& Instance()
        {
            static ProductFactory<ProductType_t> instance;
            return instance;
        }

        // 产品注册
        void RegisterProduct(IProductRegistrar<ProductType_t>* registrar, std::string name)
        {
            m_ProductRegistry[name] = registrar;
        }

        // 根据名字,获取对应具体的产品对象
        std::shared_ptr<ProductType_t> GetProduct(std::string name)
        {
            if (m_ProductRegistry.find(name) != m_ProductRegistry.end())
                return m_ProductRegistry[name]->CreateProduct();
            else
                return nullptr;
        }

    protected:
        ProductFactory() = default;
        ~ProductFactory() = default;
        ProductFactory(const ProductFactory&) = delete;
        ProductFactory& operator=(const ProductFactory&) = delete;

        // 保存注册过的产品,key:产品名字 , value:产品类型
        std::map<std::string, IProductRegistrar<ProductType_t>*> m_ProductRegistry;
    };

    // 产品注册模板类,用于创建具体产品和从工厂里注册产品
    template <class ProductType_t, class ProductImpl_t>
    class ProductRegistrar : public IProductRegistrar<ProductType_t>
    {
    public:
        // 构造函数,用于注册产品到工厂,只能显示调用
        explicit ProductRegistrar(std::string name)
        {
            // 通过工厂单例把产品注册到工厂
            ProductFactory<ProductType_t>::Instance().RegisterProduct(this, name);
        }
        // 创建具体产品对象指针
        std::shared_ptr<ProductType_t> CreateProduct()
        {
            return std::make_shared<ProductImpl_t>();
        }
    };
}

#endif
#include "FactoryMethod.h"
#include <iostream>

// 基类 鞋子
class Shoes
{
public:
    Shoes()
    {
        std::cout << "鞋子 制造" << std::endl;
    }

    ~Shoes()
    {
        std::cout << "鞋子 销毁" << std::endl;
    }
    virtual void Show() = 0;
   // virtual ~Shoes() = default;
};

// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;
    }
    NiKeShoes()
    {
        std::cout << "耐克球鞋 制造" << std::endl;
    }

    ~NiKeShoes()
    {
        std::cout << "耐克球鞋 销毁" << std::endl;
    }
};

// 基类 衣服
class Clothe
{
public:
    Clothe()
    {
        std::cout << "衣服 制造" << std::endl;
    }

    ~Clothe()
    {
        std::cout << "衣服 销毁" << std::endl;
    }
    virtual void Show() = 0;
  //  virtual ~Clothe() = default;
};

// 优衣库衣服
class UniqloClothe : public Clothe
{
public:
    void Show()
    {
        std::cout << "我是优衣库衣服,我的广告语:I am Uniqlo" << std::endl;
    }

    UniqloClothe()
    {
        std::cout << "优衣库衣服 制造" << std::endl;
    }

    ~UniqloClothe()
    {
        std::cout << "优衣库衣服 销毁" << std::endl;
    }
};


int main()
{
    {
        // ========================== 生产耐克球鞋过程 ===========================//
        thatboy::ProductRegistrar<Shoes, NiKeShoes> nikeShoes("nike");
        auto pNiKeShoes = thatboy::ProductFactory<Shoes>::Instance().GetProduct("nike");
        auto pNiKeShoes2 = thatboy::ProductFactory<Shoes>::Instance().GetProduct("nike");

        pNiKeShoes->Show();
    }
    {
        // ========================== 生产优衣库衣服过程 ===========================//
        thatboy::ProductRegistrar<Clothe, UniqloClothe> adidasShoes("uniqlo");
        auto pUniqloClothe = thatboy::ProductFactory<Clothe>::Instance().GetProduct("uniqlo");

        pUniqloClothe->Show();
    }
    return 0;
}
鞋子 制造
耐克球鞋 制造
鞋子 制造
耐克球鞋 制造
我是耐克球鞋,我的广告语:Just do it
耐克球鞋 销毁
鞋子 销毁
耐克球鞋 销毁
鞋子 销毁
衣服 制造
优衣库衣服 制造
我是优衣库衣服,我的广告语:I am Uniqlo
优衣库衣服 销毁
衣服 销毁

以上是关于工厂模式(产品注册模板类+单例工厂模板类)的主要内容,如果未能解决你的问题,请参考以下文章

用模板类特化的方式实现工厂模式

1.工厂模式

C++ 工厂模式 类模板实现

C++ 工厂模式 类模板实现

设计模式

设计模式