簡單工廠模式,又稱為靜態工廠方法模式(staticfactory method),除了單件模式之外,大約是23種Gof歸納的常見模式之中最簡單的一種了。簡單的講,它就是用工廠類的一個靜態方法來創建對象。這樣,我們可以做到利用工廠類的靜態方法統一管理對象的創建。
靜態方法根據傳入的字符串參數決定創建哪一個具體的對象,這樣,客戶端只需要知需要告訴工廠,它需要什麼對象,工廠就會根據客戶端的指令創建相應的對象實例,實現了客戶端和對象創建的分離,解開了兩者之間的耦合。
靜態工廠推遲了對象的實例化。因為靜態工廠是根據傳入的字符串決定對象的實例化,所以我們可以通過配置文件決定工廠所創建的具體對象,這樣我們可以通過配置文件修改代碼的行為而無需對代碼進行重新編譯。
我們還是來看一個實際的例子。比如我們要創建一批音樂盒,包括可以播放小提琴音樂的音樂盒和播放鋼琴音樂的音樂盒。使用簡單工廠模式,我們可以將這個創建過程實現如下:
#include "stdafx.h" #include <string> #include <iostream> #include <memory> using namespace std; // 抽象的產品類 class IMusicBox { public: virtual void playMusic() = 0; }; // 具體的產品 class ViolinBox : public IMusicBox { public: void playMusic() { cout<<"播放小提琴音樂"; } }; class PianoBox : public IMusicBox { public: void playMusic() { cout<<"播放鋼琴音樂"; } }; // 工廠類 class MusicBoxFactory { public: // 工廠類的靜態方法 // 這個方法根據傳入的字符串參數返回創建的對象 static IMusicBox* createMusicBox(string strName) { IMusicBox* pBox = NULL; if("Violin" == strName) { return new ViolinBox(); } else if( "Piano" == strName) { return new PianoBox(); } else { return nullptr; } } }; int _tmain(int argc, _TCHAR* argv[]) { // 創建對象 shared_ptr pBox( MusicBoxFactory::createMusicBox("Violin")); pBox->playMusic(); // 利用工廠創建新的對象 pBox.reset(MusicBoxFactory::createMusicBox("Piano")); pBox->playMusic(); return 0; } #include "stdafx.h" #include <string> #include <iostream> #include <memory> using namespace std; // 抽象的產品類 class IMusicBox { public: virtual void playMusic() = 0; }; // 具體的產品 class ViolinBox : public IMusicBox { public: void playMusic() { cout<<"播放小提琴音樂"; } }; class PianoBox : public IMusicBox { public: void playMusic() { cout<<"播放鋼琴音樂"; } }; // 工廠類 class MusicBoxFactory { public: // 工廠類的靜態方法 // 這個方法根據傳入的字符串參數返回創建的對象 static IMusicBox* createMusicBox(string strName) { IMusicBox* pBox = NULL; if("Violin" == strName) { return new ViolinBox(); } else if( "Piano" == strName) { return new PianoBox(); } else { return nullptr; } } }; int _tmain(int argc, _TCHAR* argv[]) { // 創建對象 shared_ptr pBox( MusicBoxFactory::createMusicBox("Violin")); pBox->playMusic(); // 利用工廠創建新的對象 pBox.reset(MusicBoxFactory::createMusicBox("Piano")); pBox->playMusic(); return 0; }
從這裡我們也可以看到,簡單工廠模式的實現也非常簡單,首先創建一個抽象的產品類,這裡的IMusicBox,工廠方法需要利用這個抽象類來代表它所創建的產品,而不用管到底是什麼產品。然後分貝實現具體的產品,ViolinBox和PianoBox,也就是我們具體要創建的對象。最後創建一個工廠類MusicBoxFactory並實現一個靜態的函數,這個函數接受一個字符串作為參數,這個字符串就是客戶端的指令,這個函數將根據這個字符串創建具體的產品。
這樣,客戶端只需要告訴簡單工廠,它需要什麼對象,就能夠從工廠獲得這個對象實例。對象的創建工作,都由簡單工廠來完成了。
當然,簡單工廠也還是有一定的局限,比如,它使用簡單的實符串比較來決定要創建的對象,當工廠負責創建的對象增多時,將是一個很麻煩的事情。Gof後面總結的抽象工廠和工廠方法都是對簡單工廠模式的某種形式上的升級,彌補了簡單工廠的某些缺點。將這三個模式對比起來學習,將更加有助於我們更好的理解這三個創建型模式。