日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php框架 > 框架設計 > C++利用反射和簡單工廠模式實現業務模塊解耦

C++利用反射和簡單工廠模式實現業務模塊解耦

來源:程序員人生   發布時間:2015-04-03 08:17:30 閱讀次數:4452次

1. 業務說明

為了便于說明,舉1個簡單的例子。假定現在有1個項目需要建立1個和銀行交互的平臺,目前只接入工商銀行,后續接入其他銀行,每一個銀行的業務都有差異,報文格式可能也不1致。

這里只羅列幾個扼要的流程,僅包括拼報文,發送報文,接收報文,解析報文,其余整體架構和后續處理等內容省略。

2. 初步設計

創建1個銀行交互類 BankOpt,包括4個函數:

int setMsg(); //拼報文 int sendMsg(); //發送報文 int getMsg(); //接收報文 int parseMsg(); //解析報文

然后在每一個函數中通過if-else來判斷具體是哪個銀行,以后進行相應的處理。

這類設計在剛開發的時候非常方便,代碼量少,但是如果后續需要接入另外1個銀行時就需要改動BankOpt類,不符合設計模式中的開放-封閉原則。而且單個函數中將來可能會有大量的if-else,使代碼可讀性降落。

3. 簡單工廠模式

通過簡單工廠模式,我們可以創建1個專門的工廠類用于實例化1個適合的銀行交互類,只需要這個銀行交互類具有共同的接口便可。

首先,為了實現更好的復用,把各個銀行交互類中相同的部份抽象出來,構成1個銀行交互基類,代碼以下:

class BaseBank { public: virtual int setMsg() = 0; virtual int sendMsg() = 0; virtual int getMsg() = 0; virtual int parseMsg() = 0; };

這里僅僅聲明了4個純虛函數,具體的業務邏輯在子類中實現。

創建兩個銀行交互子類GSBank(工商銀行)和RMBank(人民銀行),繼承BaseBank,實現4個虛函數。

  • 創建1個工廠類
class BankFactory { public: BaseBank* createBank(const string& bank_name) { if (bank_name == “GSBank”) return new GSBank(); else if (bank_name == “RMBank”) return new RMBank(); } };

工廠類中有1個createBank函數,用于根據銀行編碼創建相應的實例并返回其基類指針,這樣我們只需要通過基類指針調用相干函數便可。

  • 在主流程中調用
BankFactory bf; BaseBank* t = (BaseBank*)bf.createBank(bank_name); if (t == NULL) { cout << "銀行編碼毛?。? << endl; return 2; } t->setMsg(); t->sendMsg(); t->getMsg(); t->parseMsg();
  • 優缺點
    利用簡單工廠模式,當我們后續接入另外的銀行時,只需要添加具體的銀行交互類,實現業務函數,然后在工廠類的createBank函數中添加1個else if子句。相對原來的設計已改進很多了,但是依然需要修改原來的工廠類的代碼,沒有完全實現解耦。

4. 反射

反射在java的1些框架中使用的比較多,而且用起來非常方便。C++本身其實不支持,但是我們可以摹擬1些簡單的特性。

我們需要1種能夠根據字符串動態獲得對應的銀行交互類的實例的方法。這樣在工廠類的createBank方法中就能夠根據字符串直接獲得對應銀行交互類的實例,而不需要再每次通過新增else if 子句來新增1個銀行接口。

也就是說,利用反射和簡單工廠模式,下次當我們需要新增1個銀行接口的時候只需要新增1個銀行交互類便可,不需要修改原來的任何代碼,實現了業務上的解耦。

  • 如何在C++中實現反射
    1. 需要1個全局的map用于存儲類的信息和創建實例的函數
    2. 需要反射的類需要提供1個用于創建本身實例的函數
    3. 利用類的靜態變量在程序啟動的時候會進行初始化來在全局map中將類名及創建實例的函數存入map中

相干代碼以下:

typedef void* (*register_func)(); class Class { public: static void* newInstance(const string& class_name) { map<string, register_func>::iterator it = m_register.find(class_name); if (it == m_register.end()) return NULL; else return it->second(); } static void registerClass(const string& class_name, register_func func) { m_register[class_name] = func; } private: /* key is class name and value is function to create instance of class */ static map<string, register_func> m_register; }; class Register { public: Register(const string& class_name, register_func func) { Class::registerClass(class_name, func); } }; #define REGISTER_CLASS(class_name) class class_name##Register { public: static void* newInstance() { return new class_name; } private: static const Register reg; }; const Register class_name##Register::reg(#class_name,class_name##Register::newInstance);

還需要修改工廠類的createBank函數,利用Class的newInstance函數來創建實例:

BaseBank* createBank(const string& bank_name) { return (BaseBank*)Class::newInstance(bank_name); }

Class類中的m_register變量是static類型的map,相當于全局變量。

newInstance函數,傳入類名,查找map,調用回調函數,返回1個對應類的實例。
registerClass函數傳入類名和用于創建實例的回調函數并將信息存入全局的map中。

Register類只有1個構造函數,會調用Class的registerClass函數完成注冊。

利用宏定義,在每個需要反射的類后面額外增加1個類,其中有1個Register類型的static const變量,這樣在程序啟動的時候就會完成初始化調用Register類的構造函數,完成注冊。

以后只需要在需要反射的類,例如在工商銀行交互類 GSBank 后面加上1條宏定義:
REGISTER_CLASS(GSBank) 就能夠通過工廠類傳入”GSBank”字符串取得工商銀行交互類的實例。

5. 測試

工商銀行

人民銀行

通過傳入不同的銀行編碼,會實例化不同的銀行交互類,并且履行其對應的函數。

如果需要增加新的銀行接口,例如農業銀行,只需要新增1個NYBank類,實現具體的業務邏輯,不需要改動原來的任何代碼,傳入NYBank字符串,就會履行農業銀行相干的處理流程。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 亚洲欧洲成人av每日更新 | 免费久久精品 | 久久99精品久久久久久国产越南 | 天天射天天草 | 国产在线网 | 62久久久成人精品电影 | av在线入口 | 国产精品久久久久久久婷婷 | 久久这里精品 | 国产精品日韩在线观看一区二区 | 免费福利电影 | 久久99精品久久久久婷综合 | 国产一二三区在线观看 | 国产福利专区 | 三级av在线播放 | 亚洲成人精品久久久 | 久久久性| 亚洲精品亚洲人成人网 | 亚洲精品一区二区三区中文字幕 | 久久都是精品 | av免费网站在线观看 | 欧美日韩国产中文 | 久久国产一区二区 | 91大片 | 国产韩国精品一区二区三区 | 免费视频一二三区 | 国产一区二区高清视频 | 国产精品视频久久 | 亚洲精品国产成人久久av盗摄 | www.99re| 精品一区二区三区蜜桃 | 精品久久久影院 | 欧美精品成人 | 国产不卡视频在线 | 99国产精品99久久久久久 | 精品国产乱码久久久久久牛牛 | 在线中文字幕亚洲 | 国产精品福利一区 | 成人午夜电影网 | 国产最新精品视频 | 欧美日韩精品免费观看 |