1. 程式人生 > >用模板類特化的方式實現工廠模式

用模板類特化的方式實現工廠模式

inter ase ride ext 作者 urn char ostream protect

關於工廠模式的相關概念,這裏不贅述,以下給出一種使用模板類特化的方式實現示例:


/**
 * @file    factory.cpp
 * <pre>
 * Copyright (c) 2019, Gaaagaa All rights reserved.
 * 
 * 文件名稱:factory.cpp
 * 創建日期:2019年02月17日
 * 文件標識:
 * 文件摘要:工廠模式的實現示例代碼。
 * 編譯命令:g++ -Wall -std=c++11 -o factory factory.cpp
 * 
 * 當前版本:1.0.0.0
 * 作    者:
 * 完成日期:2019年02月17日
 * 版本摘要:
 * 
 * 歷史版本:
 * 原作者  :
 * 完成日期:
 * 版本摘要:
 * </pre>
 */

#include <map>
#include <iostream>

////////////////////////////////////////////////////////////////////////////////

class x_product_t
{
    // constructor/destructor
public:
    x_product_t(void) {  }
    virtual ~x_product_t(void) {  }

    // extensible interfaces
public:
    virtual int type(void) const = 0;
};

template< typename _Ty, int _Ptype >
class x_product_template_t : public x_product_t
{
    // common data types
public:
    typedef enum emConstValue
    {
        ECV_PRODUCT_TYPE  = _Ptype,  ///< x_product_t 的類型
    } emConstValue;

    using x_type_t  = _Ty;
    using x_super_t = x_product_template_t< _Ty, _Ptype >;

    // common invoking
public:
    static x_product_t * build(void)
    {
        return (new x_type_t());
    }

    // constructor/destructor
protected:
    x_product_template_t(void) {  }
    virtual ~x_product_template_t(void) {  }

    // overrides
public:
    virtual int type(void) const override
    {
        return _Ptype;
    }
};

//====================================================================

class x_factory_t
{
    // common data types
public:
    typedef x_product_t * (* x_func_build_t)(void);

    // constructor/destructor
public:
    x_factory_t(void)  {  }
    ~x_factory_t(void) {  }

    // public interfaces
public:
    bool register_ptype(int xtype, x_func_build_t xfunc_build)
    {
        std::map< int, x_func_build_t >::iterator itfind = m_map_func_build.find(xtype);
        if (itfind == m_map_func_build.end())
        {
            m_map_func_build.insert(std::make_pair(xtype, xfunc_build));
            return true;
        }

        return false;
    }

    void unregister_ptype(int xtype)
    {
        m_map_func_build.erase(xtype);
    }

    x_product_t * build(int xtype)
    {
        std::map< int, x_func_build_t >::iterator itfind = m_map_func_build.find(xtype);
        if (itfind != m_map_func_build.end())
        {
            return itfind->second();
        }

        return nullptr;
    }

    // data members
private:
    std::map< int, x_func_build_t >  m_map_func_build;
};

//====================================================================

typedef enum emProductType
{
    EPT_PRODUCT_A = 100,
    EPT_PRODUCT_B = 200,
    EPT_PRODUCT_C = 300,
} emProductType;

class x_product_A_t : public x_product_template_t< x_product_A_t, EPT_PRODUCT_A >
{
    friend x_super_t;

    // constructor/destructor
protected:
    x_product_A_t(void) { std::cout << "build : x_product_A_t" << std::endl; }
    virtual ~x_product_A_t(void) { std::cout << "destroy : x_product_A_t" << std::endl; }
};

class x_product_B_t : public x_product_template_t< x_product_B_t, EPT_PRODUCT_B >
{
    friend x_super_t;

    // constructor/destructor
protected:
    x_product_B_t(void) { std::cout << "build : x_product_B_t" << std::endl; }
    virtual ~x_product_B_t(void) { std::cout << "destroy : x_product_B_t" << std::endl; }
};

class x_product_C_t : public x_product_template_t< x_product_C_t, EPT_PRODUCT_C >
{
    friend x_super_t;

    // constructor/destructor
protected:
    x_product_C_t(void) { std::cout << "build : x_product_C_t" << std::endl; }
    virtual ~x_product_C_t(void) { std::cout << "destroy : x_product_C_t" << std::endl; }
};

//====================================================================

int main(int argc, char * argv[])
{
    x_factory_t xfactory;

    //======================================
    // 註冊

#define REGISTER_PRODUCT(name)  xfactory.register_ptype(name::ECV_PRODUCT_TYPE, &name::build)

    REGISTER_PRODUCT(x_product_A_t);
    REGISTER_PRODUCT(x_product_B_t);
    REGISTER_PRODUCT(x_product_C_t);

#undef REGISTER_PRODUCT

    //======================================
    // 生產

    x_product_t * xpdt = nullptr;

    xpdt = xfactory.build(EPT_PRODUCT_A);
    std::cout << "xdpt type : " << xpdt->type() << std::endl;
    delete xpdt;

    xpdt = xfactory.build(EPT_PRODUCT_B);
    std::cout << "xdpt type : " << xpdt->type() << std::endl;
    delete xpdt;

    xpdt = xfactory.build(EPT_PRODUCT_C);
    std::cout << "xdpt type : " << xpdt->type() << std::endl;
    delete xpdt;

    //======================================

    return 0;
}

用模板類特化的方式實現工廠模式