程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 設計模式應用與發展之工廠模式 c++篇

設計模式應用與發展之工廠模式 c++篇

編輯:C++入門知識

1     引子
這是一個幸福的時代,特別是作為一個java程序員(感慨一下,java程序員確實比C/C++程序員幸福)。

基於我個人的一貫風格,我不准備采用大量技術術語和官腔講述這次的主題:工廠模式應用與發展。今時今日提到工廠模式,相信絕大部分的人都已經對這個詞匯有所了解(恩恩,注意我的用詞,我沒說“對他的概念、含義和用途有所了解”)。

那麼,在開始進入正題之前,我們先回顧一下工廠模式的作用(我不准備列舉在這,自己想想)。

OK,下面開始我的講述,請大家耐心點(是的,我怕有人半途而廢;噢,再啰嗦一下,重點在示例代碼)!

2     石器時代
2.1   痛苦的開始
據說原始人類所使用的工具的產生有很大的隨機性。例如這樣的情況:最開始大家吃肉肉,一窩蜂撲上去撕咬;後來可能覺得不衛生(也可能是覺得咬起來牙齒疼,也可能是覺得自己每次都咬不過別人),於是按自己牙齒的模樣,找些放大比例的動物牙齒(或者石頭),嘗試著割肉,發現挺好使的,於是工具產生了。

代碼界同樣有這樣的事情發生(產品的童鞋要我們為每個名人設計一句話):

...

if(strcmp(name, "billgates") == 0) {

       printf("Doyou like Win8?");

} else if(strcmp(name, "Stevejobs") == 0) {

       printf("sonice iPhone.");

} else if(strcmp(name, "Zuckerberg")== 0) {

       printf("Welcometo facebook.");

} else {

...

看上去這樣沒有什麼不妥,是不是?

然而,事情遠遠沒有這麼簡單。

“花心”的產品童鞋總會給我們提點新要求,有木有?他們很可能覺得每個名人都應該充分體現自己的個性,要求為他們增加肢體語言什麼的。有木有?

好吧,我們的痛苦從此開始了……

2.2   夢想
我猜想,原始人類估計不像我們現在這麼貪婪,他們在尋找牙齒與石頭的時候,很可能是在想:老天爺,賜我一把割肉神器吧(而不是:老天爺,賜我一具不用吃飯的肉體吧)!當然,在得到神器的那一天來臨之前,我們的原始先祖們,還是不得不繼續尋找更鋒利的牙齒與石頭。

是的,代碼界也發生了一些變化:

...

void billgatesShowtime() {

       printf("Do you like Win8?");

       printf("Andput up his hands.");

}

...

if(strcmp(name, "billgates") == 0) {

       BillgatesShowtime();

} else if(strcmp(name, "Stevejobs") == 0) {

       StevejobsShowtime();

} else if(strcmp(name,"Zuckerberg") == 0) {

       ZuckerbergShowtime();

} else {

...

噢,看上去確實好多了,我們可以讓老比爾給大家舉手示意了,不是嗎?

是的,你興奮了很久,甚至晚上睡覺都帶著醉人的笑容。

順便還做了個夢:你站在雲端,覺得孤獨,便心血來潮的說:要有比爾,於是比爾出現了;你又說:要有喬布斯,於是喬布斯出現了;你接著說:要有馬化騰……

3     青銅器時代
恩,或許在這之前,還要經歷一個後石器時代,在那個過程中,我們使用typedef定義函數指針,並建立名字與函數地址關聯的數組(或者map),使代碼變得更優雅;這確實是一個很大的改善,但仍然還不足以代表設計模式上的進步,所以我們忽視他的存在。

3.1   痛苦的持續
哦,時光悠悠,石器時代過去了。

我們的先祖仍在期待神器,仍在尋找更鋒利的割肉工具……

代碼界,你跌坐在屏幕前,嘴裡念念有詞:果然應驗了,我TM說“要有馬化騰”干毛啊?

是的,可惡的產品童鞋說了,要把馬化騰加入這個名人行列,同時還要抱一只企鵝。

在一萬只草泥馬奔騰過後,你從泥濘的草原上站起來,向著太陽的方向,前進前進前進進……

3.2   曙光
好在先祖們發現了青銅,相比之下,青銅比石頭和牙齒更靠譜,還能自己決定著割肉工具的外形(嚯嚯,越拉風越好哇)。

代碼界裡,你也在進步:

...

\

class CPeople {

       virtualvoid showtime() = 0;

};

...

class CXiaomage : public CPeople {

       voidshowtime() {

              printf("Fuck360.");

              printf("Doyou like QQ pets?");

       }

};

...

class CFamousPersons {

private:

map<string,CPeople*> peoples;

 

public:

CFamousPersons(){

              peoples.insert(pair<string,CPeople*>("bill gates", new CBillgates()));

              peoples.insert(pair<string,CPeople*>("steve jobs", new CStevejobs()));

              peoples.insert(pair<string,CPeople*>("馬化騰", new CXiaomage()));

              …

       }

 

       People*find(string name) {

              map<string,CPeople*>::iterator iter = peoples.find(name);

              if(iter!= peoples.end())

                     returniter->second;

              returnNULL;

       }

};

...

CFamousPersons famousPersons;

People* people = famousPersons.find(name);

 

if(people != NULL) {

       people->showtime();

}

...

咦?代碼好像變多了,但我們為你自豪;因為這已經是一個完整的工廠模式的實現了。

是的,代碼可讀性增強了,邏輯結構也清晰了很多,對不對。關鍵是你再也不同擔心產品給你增加名人,不用擔心名人的各種性格和癖好。

於是你睡了個好覺,但你誠惶誠恐,不敢做夢。

4     鐵器時代
4.1   憤怒的燃燒
青銅的冶煉和鍛造技術已經達到了巅峰。吳鉤、魚腸、干將、莫邪……,喔噢,這已經是割肉神器了不?

仿佛從現在開始,擔心先祖的生活已經有點多余了。

是的,因為代碼界裡,名人的數量已經達到了10000+(名人的各種性格和癖好,也讓你震驚到了無以復加)。

你已無數次的被這份名單中人從夢中驚醒,你的生活開始變得枯燥,你的世界漸漸黑白。仿佛你的生活就是為了這份名單而存在(有的名人改名了;有的名人換公司了;有的名人變性了,擦啊啊啊……)。

CFamousPersons已經被神獸草泥馬踐踏了無數次,而且變成了工程裡面個頭最大的源代碼文件;每次你從peoples裡找名人的時候,這份超長的名單幾乎亮瞎了你的钛合金眼。

一次次的代碼更新,SVN上的代碼號直接蹦到了5位數;當你部署代碼時,看著運維冒著幽光的怨恨眼神,你叔忍了,但你嬸認為絕不能忍;於是你發糞圖牆……

4.2   福音
有一天,某位先祖發現自己的神器青銅大劍居然被一柄小匕首斬斷了,擦啊,這是什麼玩意?超神器?

呵呵,豬腳模式開啟了,在代碼界,你也發現了“神器”。

你先把這個名單弄到了數據庫裡(表名famous_persons):

 

然後,你用這把“神器”大刀闊斧把臃腫的CFamousPersons剁的稀爛。

再然後,你重造了一個輪子:

...

typedef void* (__stdcall*PExportClass)();

class CFamousPersons {

private:

CConnectionconn;

...

       constchar* findPlugin(string name) {

              char*pluginFile = "";

              stringsqlCmd = "SELECT * FROM famous_persons WHERE Name=\"";

sqlCmd +=name;

sqlCmd +="\"";

              CRecordset*rs = conn.executeQuery(sqlCmd);

 

              if(!(rs->Eof()|| rs->Bof())) {

pluginFile= new char[256];

strncpy(pluginFile,rs->fieldValue(2), 256);

              }

 

              rs->destroy();

 

              returnpluginFile;

       }

 

public:

CPeople*find(string name) {

              CPeople*people = NULL;

              stringpluginFile = findPlugin(name);

 

              if(!pluginFile.empty()){

                     HMODULEplugin = LoadLibrary(pluginFile);

                     if(plugin){

                            PExportClassexportClass = (PExportClass)GetProcAddress(plugin, "exportClass");

                            if(exportClass)

                                   people = (CPeople*)exportClass();

                     }

              }

 

              returnpeople;

       }

};

...

哇噢,酷!從此,你遠離了CFamousPersons;遠離了那糟糕的日子。生活貌似從這一刻又重新燃起了希望……

嗯,出乎意料的,你又做夢了,在夢裡,你拋棄了數據庫,增加了好些個輔助模塊,代碼簡潔而優雅,充滿美感……

5     蒸汽機時代
5.1   貪婪的欲望
終於,當我們的先祖們還沉浸在冷兵器時代,突如其來的炮火,把國門轟得稀爛;戰火不斷,黃金白銀都頂不住火藥的貪婪……

代碼界裡,你也終究沒來得及親自嘗試拋棄數據庫的喜悅,各種框架猝不及防的降臨。

5.2   神賜
好吧,時間線已經很接近現實,不過先祖們始終沒有得到神賜,一切都靠自力更生。

代碼界裡不一樣,我們有了很多框架(神器)。比如說COM(恩,還有個學模學樣的跨平台的XPCOM)。說起COM(應算是業界如雷灌招風耳的大神器了),聽上去好像不是很沾邊,但COM的CreateInstance其實現原理和應用機制,仍然是工廠模式。

當然,實現形式有了很大變化,就如他不采用名字,而是采用GUID映射;他不用數據庫,而是使用注冊表保存映射關系;他甚至還有自己的內存機制;有自己的數據類型等等。(廣告:預知詳情,請關注後續分享)。

6     另一個夢想

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved