標籤:設計模式 原廠模式
之前看了一些關於原廠模式和抽象原廠模式的資料,瞭解了原廠模式和抽象原廠模式的特點和區別。今天再回來看自己之前寫的筆記,又開始迷惑了,下面把自己的一些迷惑和想法記錄下來。
1.什麼地方會用到簡單原廠模式?在很多開源庫中都會出現跨平台的問題。假設有一個視窗模組(即為一個dll),該模組提供視窗的準系統比如設定標題、設定視窗背景顏色等。在不同的平台裡,建立視窗需要調用不同的API,比如windows平台,建立視窗可以調用MFC或者windows的API,在linux平台建立視窗則需要調用X11的API,因此不同平台需要不同的視窗類別來實現。設有基類window,子類win_window, linux_window, android_window,代碼如下:
在window.h中只定義了抽象類別window的介面(這裡用來作為例子說明簡單原廠模式的使用環境,因此只簡單定義了三個介面,且不做功能的實現)和create_window函數。
//window.hclass window{ public: virtual ~window(){};//必須是虛函數 public: virtual void set_titile(const char* title_) = 0;//純虛函數 virtual void set_background_color(int r_, int g_, int b_, int a_) = 0; virtual void set_size(int width_, int height_) = 0;};window* create_window();
在window.cpp中定義並實現具體子類win_window、linux_window、android_window及函數create_window。代碼如下:
//window.cppclass linux_window:public window{ public: ~win_window(){} public: void set_title(const char* title_){\\暫時不實現功能} void set_background_color(int r_, int g_, int b_, int a_){\\暫時不實現功能} void set_size(int width_, int height_){\\暫時不實現功能}};class android_window:public window{ public: ~win_window(){} public: void set_title(const char* title_){\\暫時不實現功能} void set_background_color(int r_, int g_, int b_, int a_){\\暫時不實現功能} void set_size(int width_, int height_){\\暫時不實現功能}};window* create_window(){ window* wind = NULL; if(system_str == "win32") wind = new win_window(); else if(system_str == "linux") wind = new linux_window(); else if(system_str == "android") wind = new android_window(); else wind = NULL; return wind;}
上面的函數create_window根據不同的系統產生不同的window類,使得外部調用時,不需要考慮跨平台的問題,在任何平台上,外部調用建立視窗的代碼都只有一份。請注意一點,我們在看設計模式書的時候,簡單原廠模式一般都是一個類,而我寫了一個函數說使用了簡單原廠模式,這是不是錯誤的呢?這裡沒有錯誤,設計模型給我們提供的是一種思路,在學習設計模式的時候,我們要掌握重點,學會變通,不要太注重條條框框。
到這裡也許還有人會問:如果不定義create_window函數,將create_window函數的代碼放到外部建立視窗的地方,不也是可以的嗎?
沒錯,這樣也是可以的。但是使用這種方式和使用create_window函數封裝建立視窗類別的過程比起來,使用create_window有兩個優點:(1)外部調用時,只需調用create_window函數,代碼簡潔,邏輯清晰;(2)如果你夠細心的話會發現,我在window.h標頭檔中只定義了window抽象類別和create_window函數,並沒有聲明其他三個子類,而是在window.cpp檔案中對三個子類進行聲明和實現的。這樣做使得三個子類對於外部來說是透明的,外部根本不知道有這三個子類的存在。
這裡你也許會問,三個子類對外部透明,有什麼好處?假設這樣一種情況:如果我換了一個視窗模組,這個視窗模組也定義了window抽象類別和create_window,但是子類的名稱和上一個視窗模組都不一樣了,這時候就能看出抽象類別對外部透明的好處了。因為之前外部調用都是使用的create_window函數,所以雖然視窗模組改變了,但是只要window抽象類別和create_window沒有改變,外部不需要改變任何代碼就可以使用新的視窗模組。
2.什麼地方會用到原廠模式和抽象原廠模式?
3.為什麼要用原廠模式和抽象原廠模式?
問題2和3其實可以在問題1裡面找到答案。使用原廠模式和抽象原廠模式都是為了隔離對象的建立過程,使得具體類對外部調用透明,即外部不知道有子類的存在。這樣在對子類做修改後,外部可以不做修改或者只做極少的修改就可以了。
以上內容純屬自己的一些理解,如果哪裡錯了,歡迎大家指正。
關於原廠模式的一些反思