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