偉創力(世界500強企業),公司有筆記本生產車間、電視機車間、空調車間、電話生產等車間,各生產車間各行其責,生產出不同類型的產品。偉創力不再是生產單一產品的企業,而是生產出多種不同類型的產品,各產品屬於不同產品等級結構中。在設計模式中,也存在一種類似的模式,可以創建一系列產品,這些產品位於不同產品等級結構,產品之間可以沒有任何聯系,但他們組合起來,可以成為一個產品族,稱之為抽象工廠模式。
在工廠方法模式中具體工廠負責生產具體的產品,每一個具體工廠對應一種具體產品,工廠方法具有唯一性。但是有時候我們希望一個工廠可以提供多個產品對象,而不是單一的產品對象,如一個電器工廠,它可以生產電視機、電冰箱、空調等多種電器,而不是只生產某一種電器。為了更好地理解抽象工廠模式,我們先引入兩個概念:
(1) 產品等級結構:產品等級結構即產品的繼承結構,如一個抽象類是電視機,其子類有海爾電視機、TCL電視機,創維電視機。則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是其子類。
產品等級結構圖
(2) 產品族<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPqO61Nqz6c/zuaSzp8Sjyr3W0KOsPHN0cm9uZz6y+sa31+XKx9a408nNrNK7uPa5pLOnyfqy+rXEo6zOu9PasrvNrLL6xre1yLy2veG5udbQtcTSu9fpsvrGtzwvc3Ryb25nPqOsyOe6o7b7tefG97mks6fJ+rL6tcS6o7b7tefK07v6oaK6o7b7teex+c/koaO6o7b7tefK07v6zrvT2rXnytO7+rL6xre1yLy2veG5udbQo6y6o7b7teex+c/kzrvT2rXnsfnP5LL6xre1yLy2veG5udbQo6y6o7b7tefK07v6oaK6o7b7teex+c/kubmzycHL0ru49rL6xrfX5TwvcD4KPHA+CjxpbWcgc3JjPQ=="http://www.2cto.com/uploadfile/Collfiles/20140818/20140818085015188.png" alt="\">
產品族圖
當系統所提供的工廠生產的具體產品並不是一個簡單的對象,而是多個位於不同產品等級結構、屬於不同類型的具體產品時就可以使用抽象工廠模式。抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形式。抽象工廠模式與工廠方法模式最大的區別在於,工廠方法模式針對的是一個產品等級結構,而抽象工廠模式需要面對多個產品等級結構,一個工廠等級結構可以負責多個不同產品等級結構中的產品對象的創建。當一個工廠等級結構可以創建出分屬於不同產品等級結構的一個產品族中的所有對象時,抽象工廠模式比工廠方法模式更為簡單、更有效率。
2、BeyondCompare的設計與實現
BeyondCompare是一款代碼比較軟件,能夠比較不同版本的代碼之間的差異,類似SVN版本控制器。例如:在版本1基礎之上進行修改升級為版本2,BeycongComapare能夠對版本1和2代碼進行比較,檢測出哪些地方存在差異。需求:設計一款類似BeyondCompare的軟件,能夠在Windows平台和Linux平台下對Cpp格式和Java格式的源代碼進行比較,檢測出差異。
使用簡單工廠模式的實現方式
代碼格式類型圖
格式工廠圖
要在Windows和Linux平台下都能針對Cpp和Java代碼格式文件進行比較,考慮到擴展性,可以定義一個抽象CPP類,Windows平台下的Cpp格式和Linux平台下的Cpp格式都繼承於這個抽象Cpp類。 同時定義一個抽象Java類,Windows平台下的Java格式和Linux平台下的Java格式都繼承於這個抽象Java類
代碼格式類型實現如下:
#ifndef _PRODUCT_H_ #define _PRODUCT_H_ #includeCpp格式和Java格式是兩種不同類型的產品,因此可以提供兩個簡單工廠,一個工廠用於創建不同平台下的Cpp格式對象,另一個工廠用於創建不同平台下的Java格式對象。#include using namespace std; //抽象Cpp代碼格式類 class CppCodeStyle { public: //虛函數,用於顯示處理的代碼格式 virtual void DisplayCodeStyle() = 0; }; //Windows Cpp代碼格式 class WindowsCppCodeStyle : public CppCodeStyle { public: void DisplayCodeStyle() { cout << "我對Windows Cpp文件進行代碼比較" << endl; } }; //Linux Cpp代碼格式 class LinuxCppCodeStyle : public CppCodeStyle { public: void DisplayCodeStyle() { cout << "我對Linux Cpp文件進行代碼比較" << endl; } }; /*********************************************************/ /*********************************************************/ //抽象Java代碼格式 class JavaCodeStyle { public: //虛函數,用於顯示處理的代碼格式 virtual void DisplayCodeStyle() = 0; }; //Windows Java代碼格式 class WindowsJavaCodeStyle : public JavaCodeStyle { public: void DisplayCodeStyle() { cout << "我對Windows Java文件進行代碼比較" << endl; } }; //Linux Java代碼格式 class LinuxJavaCodeStyle : public JavaCodeStyle { public: void DisplayCodeStyle() { cout << "我對Linux Java文件進行代碼比較" << endl; } }; #endif
格式工廠實現代碼如下:
#ifndef _PRODUCT_FACTORY_H_ #define _PRODUCT_FACTORY_H_ #include "Product.h" //Cpp格式工廠 class CppProductFactory { public: //創建具體平台的Cpp,strCppType表示windows還是linux下的cpp static CppCodeStyle * CreateCpp(string strCppType) { CppCodeStyle * pCppCodeStyle = NULL; if( 0 == strcmp(strCppType.c_str(), "Windows Cpp") ) { pCppCodeStyle = new WindowsCppCodeStyle(); } else if( 0 == strcmp(strCppType.c_str(), "Linux Cpp") ) { pCppCodeStyle = new LinuxCppCodeStyle(); } else { return NULL; } return pCppCodeStyle; } }; //Java格式工廠 class JavaProductFactory { public: //創建具體平台的Java,strJavaType表示windows還是linux下的Java static JavaCodeStyle * CreateJava(string strJavaType) { JavaCodeStyle * pJavaCodeStyle = NULL; if( 0 == strcmp(strJavaType.c_str(), "Windows Java") ) { pJavaCodeStyle = new WindowsJavaCodeStyle(); } else if( 0 == strcmp(strJavaType.c_str(), "Linux Java") ) { pJavaCodeStyle = new LinuxJavaCodeStyle(); } else { return NULL; } return pJavaCodeStyle; } }; #endifCppProductFactory產品工廠用於創建windows平台和Linux平台下的Cpp格式對象,JavaProductFactory產品工廠用於創建windows平台和Linux平台下的Java格式對象。
測試文件實現代碼如下:
#includeusing namespace std; #include "Product.h" #include "ProductFactory.h" int main() { /*************創建Windows Cpp *************************************/ CppCodeStyle * pWindowsCppCodeStyle = CppProductFactory::CreateCpp("Windows Cpp"); pWindowsCppCodeStyle->DisplayCodeStyle(); /*************創建Linux Java *************************************/ JavaCodeStyle * pLinuxJavaCodeStyle = JavaProductFactory::CreateJava("Linux Java"); pLinuxJavaCodeStyle->DisplayCodeStyle(); /*************銷毀操作********************************************/ delete pWindowsCppCodeStyle; pWindowsCppCodeStyle = NULL; delete pLinuxJavaCodeStyle; pLinuxJavaCodeStyle = NULL; return 0; }
編譯並執行,結果如下: