C++簡單工廠模式的學習

我們先從最常見的C++類的一個實現開始說起,

class API
{
public:
virtual test(std::string s)=0;
protected:
API(){};
};
class ImpleOne :public API {
public:
    void test(string s) override {
        std::cout << "現在是One在執行 " << s<<std::endl;
    }
};

int main(void)
{
API * pApi=new ImpleOne();
pApi->test();
return;
}

這樣的代碼就會破壞我們面向對象的封裝性,因爲調用者會知道API和IMPLEONE的存在。

怎麼樣完成高內聚,低耦合這個要求那?

那就用一下我們的簡單工廠模式,在頭文件中

#include<iostream>
#include<string>
#include<map>
//建立函數指針 
typedef void* (*Constructor)();

//創建一個工廠.
class CObjectFactory
{
public:
    //註冊對應的類添加到容器中
    static void RegsiterClass(std::string classname, Constructor constructor)
    {
        constructors()[classname] = constructor;
    }
    //創建一個類的對象並返回
    static void* CreateObject(const std::string ClassName)
    {
        Constructor constructor = nullptr;
        if (constructors().find(ClassName) != constructors().end())
        {
            constructor = constructors().find(ClassName)->second;
        }
        if (constructor == nullptr)
        {
            return nullptr;
        }
        return (*constructor)();
    }
private:
    //返回一個容器
    static std::map<std::string, Constructor>& constructors()
    {
        static std::map<std::string, Constructor> instance;
        return instance;
    }

};

//註冊我們的類的宏定義
#define REG_CLASS(class_name) \
 class class_name##Helper{ \
 public:  \
    class_name##Helper(){ \
    CObjectFactory::RegsiterClass(#class_name,class_name##Helper::CreateObjFunc); \
    }; \
    static  void*CreateObjFunc() \
    { \
        return new class_name; \
    } \
 };\
 static class_name##Helper class_name##helper; //加入static是指只在頭文件中有效。

然後就是如何調用這個簡單工廠

 //在這裏可以通過讀取配置文件,或者直接修改REG_CLASS和CreateObject中的字符串,就可以完成對這個類的改變,或者更新 ,並不影響後面代碼的更改。
 REG_CLASS(ImpleOne)
 class AUTOFACTORY
 {
     public:
     std::shared_ptr<Api> CreateAPI()
     {
        
        std::shared_ptr<API> Apipointer(static_cast<API*>(CObjectFactory::CreateObject("ImpleOne")));
        return Apipointer;
     }
 }
 int main(void)
 {
    std::shared_ptr<Api> testpoint(AUTOFACTORY::CreateAPI());
    testpoint->test("我不是你爸爸!");
    return;
 }

總結一下:我們可以通過創建一個類作爲工廠提供我們所需要的類,並且通過一個輔助註冊的類,使我們需要的類註冊到我們的工廠裏面,我們的調用者可以不通過知道我們類中的具體實現,就可以獲取到他們所需的類,並且完好的實現了類的封裝性.我們在以後修改或者替換我們的類的時候就不會影響調用者的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章