C++設計模式——抽象工廠模式(含例項)
前言
偉創力(世界500強企業),公司有筆記本生產車間、電視機車間、空調車間、電話生產等車間,各生產車間各行其責,生產出不同型別的產品。偉創力不再是生產單一產品的企業,而是生產出多種不同型別的產品,各產品屬於不同產品等級結構中。在設計模式中,也存在一種類似的模式,可以建立一系列產品,這些產品位於不同產品等級結構,產品之間可以沒有任何聯絡,但他們組合起來,可以成為一個產品族,稱之為抽象工廠模式。
1、產品等級結構與產品族
在工廠方法模式中具體工廠負責生產具體的產品,每一個具體工廠對應一種具體產品,工廠方法具有唯一性。但是有時候我們希望一個工廠可以提供多個產品物件,而不是單一的產品物件,如一個電器工廠,它可以生產電視機、電冰箱、空調等多種電器,而不是隻生產某一種電器。為了更好地理解抽象工廠模式,我們先引入兩個概念:
(1) 產品等級結構:產品等級結構即產品的繼承結構,如一個抽象類是電視機,其子類有海爾電視機、TCL電視機,創維電視機。則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是其子類。
產品等級結構圖
(2) 產品族:在抽象工廠模式中,產品族是指由同一個工廠生產的,位於不同產品等級結構中的一組產品,如海爾電器工廠生產的海爾電視機、海爾電冰箱。海爾電視機位於電視機產品等級結構中,海爾電冰箱位於電冰箱產品等級結構中,海爾電視機、海爾電冰箱構成了一個產品族
產品族圖
當系統所提供的工廠生產的具體產品並不是一個簡單的物件,而是多個位於不同產品等級結構、屬於不同型別的具體產品時就可以使用抽象工廠模式。抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形式。
2、BeyondCompare的設計與實現
BeyondCompare是一款程式碼比較軟體,能夠比較不同版本的程式碼之間的差異,類似SVN版本控制器。例如:在版本1基礎之上進行修改升級為版本2,BeycongComapare能夠對版本1和2程式碼進行比較,檢測出哪些地方存在差異。需求:設計一款類似BeyondCompare的軟體,能夠在Windows平臺和Linux平臺下對Cpp格式和Java格式的原始碼進行比較,檢測出差異。
2.1 使用簡單工廠模式的實現方式
程式碼格式型別圖
格式工廠圖
要在Windows和Linux平臺下都能針對Cpp和Java程式碼格式檔案進行比較,考慮到擴充套件性,可以定義一個抽象CPP類,Windows平臺下的Cpp格式和Linux平臺下的Cpp格式都繼承於這個抽象Cpp類。 同時定義一個抽象Java類,Windows平臺下的Java格式和Linux平臺下的Java格式都繼承於這個抽象Java類
2.2 格式類的定義
程式碼格式型別實現如下:
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
#include <iostream>
#include <string>
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
2.3 格式工廠類的定義
Cpp格式和Java格式是兩種不同型別的產品,因此可以提供兩個簡單工廠,一個工廠用於建立不同平臺下的Cpp格式物件,另一個工廠用於建立不同平臺下的Java格式物件。格式工廠實現程式碼如下:
#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;
}
};
#endif
2.4 編譯執行結果
編譯並執行,結果如下:
2.5 簡單工程模式存在的問題及分析
使用簡單工廠模式基本上能夠實現上述的需求,但從程式執行結果來看:"我對Linux Cpp檔案進行程式碼比較和"我對Linux Java檔案進行程式碼比較",顯然是不合理的。既然是一款BeyongdCompare程式碼比較軟體,安裝在Windows下就只能對Windows下的Cpp和Java程式碼進行比較,而不能對Linux下的程式碼格式檔案進行比較。從程式執行結果來看,既能對Windows下的Cpp檔案進行比較,同時又能對Linux的Java檔案進行比較,那這個軟體到底安裝在哪個平臺上呢?顯然結果是不正確的。程式執行結果表示處理(Windows或者Linux)下的cpp格式和java格式是沒有關聯的。但實際上(Windows或者Linux)下的Cpp格式和Java格式是有關聯的。兩者組合在一起,表示能夠對Windows下的Cpp和Java檔案進行處理,或者表示能夠對Linux下的Cpp和Java檔案進行處理。那如何才能使Cpp格式產品和Java格式產品在某一個平臺上進行關聯呢? ------抽象工廠模式可以解決這個問題。3、抽象工廠模式概述
抽象工廠模式為建立一組物件提供了一種解決方案。與工廠方法模式相比,抽象工廠模式中的具體工廠不只是建立一種產品,它負責建立一族產品。抽象工廠模式定義如下:
抽象工廠模式(Abstract Factory Pattern):提供一個建立一系列相關或相互依賴物件的介面,而無須指定它們具體的類。它是一種物件建立型模式。 |
在抽象工廠模式中,每一個具體工廠都提供了多個工廠方法用於產生多種不同型別的產品,這些產品可以沒有任何的聯絡,且位於不同的產品等級中,但這些產品可以組合起來,構成了一個產品族。
抽象工廠模式結構圖
在抽象工廠模式結構圖中包含如下幾個角色:
AbstractFactory(抽象工廠):它聲明瞭一組用於建立一族產品的工廠方法,每一個工廠方法對應一種產品。這些產品可以沒有任何的聯絡,但這些產品可以組合起來,可以構成一個產品族。
ConcreteFactory(具體工廠):它實現了在抽象工廠中宣告的建立產品的工廠方法,生成一組具體產品,這些產品構成了一個產品族,每一個產品都位於某個產品等級結構中。
AbstractProduct(抽象產品):它為每種產品宣告介面,在抽象產品中聲明瞭產品所具有的業務方法。
ConcreteProduct(具體產品):它定義具體工廠生產的具體產品物件,實現抽象產品介面中宣告的業務方法。
4、使用抽象工廠實現BeyongdCompare
程式碼格式型別圖
格式工廠圖
要在Windows和Linux平臺下都能對Cpp和Java程式碼格式檔案進行比較,考慮到擴充套件性,可以定義一個抽象CPP類,Windows平臺下的Cpp格式和Linux平臺下的Cpp格式都繼承於這個抽象Cpp類。 同時定義一個抽象Java類,Windows平臺下的Java格式和Linux平臺下的Java格式都繼承於這個抽象Java類。定義一個抽象格式工廠,Windows格式工廠繼承於抽象格式工廠,用於建立Windows下的Cpp和Java格式物件。 Linux格式工廠也繼承於抽象格式工廠,用於建立Linux下的Cpp和Java格式物件。
4.1 程式碼格式型別的實現
程式碼格式型別實現如下:#ifndef _PRODUCT_H_
#define _PRODUCT_H_
#include <iostream>
#include <string>
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
BeyondCompare軟體能執行在Windows平臺和Linux平臺,每個平臺都能對Cpp檔案和Java檔案進行比較。因此可以建立一個Windows工廠,用於建立Windows下的Cpp物件和Java物件。建立一個Linux工廠,用於建立Linux下的Cpp物件和Java物件。這樣Cpp物件和Java物件就被限制在了某個平臺下。即Cpp物件和Java物件要麼同屬於Windows,要麼同屬於Linux。而不會出現使用簡單工廠模式出現的情況:"Cpp屬於Windows平臺,而Java屬於Linux平臺"。
4.2 格式工廠的實現
格式工廠實現程式碼如下:#ifndef _PRODUCT_FACTORY_H_
#define _PRODUCT_FACTORY_H_
#include "Product.h"
//抽象程式碼格式工廠
class CodeStyleFactory
{
public:
//工廠方法,建立具體的Cpp格式物件
virtual CppCodeStyle * CreateCpp() = 0;
//工廠方法,建立具體的Java格式物件
virtual JavaCodeStyle * CreateJava() = 0;
};
//Windows程式碼格式工廠
class WindowsCodeStyleFactory : public CodeStyleFactory
{
public:
//工廠方法,建立具體的Cpp格式物件
CppCodeStyle * CreateCpp()
{
CppCodeStyle * pCppCodeStyle = new WindowsCppCodeStyle();
return pCppCodeStyle;
}
//工廠方法,建立具體的Java格式物件
JavaCodeStyle * CreateJava()
{
JavaCodeStyle * pJavaCodeStyle = new WindowsJavaCodeStyle();
return pJavaCodeStyle;
}
};
//Linux程式碼格式工廠
class LinuxCodeStyleFactory : public CodeStyleFactory
{
public:
//工廠方法,建立具體的Cpp格式物件
CppCodeStyle * CreateCpp()
{
CppCodeStyle * pCppCodeStyle = new LinuxCppCodeStyle();
return pCppCodeStyle;
}
//工廠方法,建立具體的Java格式物件
JavaCodeStyle * CreateJava()
{
JavaCodeStyle * pJavaCodeStyle = new LinuxJavaCodeStyle();
return pJavaCodeStyle;
}
};
#endif
4.3 測試檔案的實現
測試檔案實現程式碼如下:#include <iostream>
using namespace std;
#include "Product.h"
#include "ProductFactory.h"
int main()
{
/*************建立Windows Cpp ************************************/
CodeStyleFactory * pWindowsCodeStyleFactory = new WindowsCodeStyleFactory();
CppCodeStyle * pWindowsCppCodeStyle = pWindowsCodeStyleFactory->CreateCpp();
pWindowsCppCodeStyle->DisplayCodeStyle();
/*************建立Windows Java ************************************/
JavaCodeStyle * pWindowsJavaCodeStyle = pWindowsCodeStyleFactory->CreateJava();
pWindowsJavaCodeStyle->DisplayCodeStyle();
cout << "***********************************" << endl;
/*************建立Linux Cpp ************************************/
CodeStyleFactory * pLinuxCodeStyleFactory = new LinuxCodeStyleFactory();
CppCodeStyle * pLinuxCppCodeStyle = pLinuxCodeStyleFactory->CreateCpp();
pLinuxCppCodeStyle->DisplayCodeStyle();
/*************建立Linux Java ************************************/
JavaCodeStyle * pLinuxJavaCodeStyle = pLinuxCodeStyleFactory->CreateJava();
pLinuxJavaCodeStyle->DisplayCodeStyle();
/*************銷燬Windows相關物件操作****************************/
delete pWindowsCodeStyleFactory;
pWindowsCodeStyleFactory = NULL;
delete pWindowsCppCodeStyle;
pWindowsCppCodeStyle = NULL;
delete pWindowsJavaCodeStyle;
pWindowsJavaCodeStyle = NULL;
/*************銷燬Linux相關物件操作****************************/
delete pLinuxCodeStyleFactory;
pLinuxCodeStyleFactory = NULL;
delete pLinuxCppCodeStyle;
pLinuxCppCodeStyle = NULL;
delete pLinuxJavaCodeStyle;
pLinuxJavaCodeStyle = NULL;
return 0;
}
4.4 執行結果
編譯並執行,程式結果如下:5、抽象工廠模式總結
簡單工廠模式和工廠方法模式都只產生一種型別的產品物件。然而在抽象工廠模式中,每一個具體工廠都提供了多個工廠方法用於產生多種不同型別的產品,這些產品可以沒有任何的聯絡,位於不同的產品等級,但這些產品可以組合起來,構成一個產品族。抽象工廠模式是工廠方法模式的進一步延伸,由於它提供了功能更為強大的工廠類並且具備較好的可擴充套件性,在軟體開發中得以廣泛應用。使用抽象工廠模式來實現在不同的作業系統中應用程式呈現與所在作業系統一致的外觀介面。
5.1.主要優點
抽象工廠模式的主要優點如下:
(1) 抽象工廠模式隔離了具體類的生成,使得客戶並不需要知道什麼被建立。由於這種隔離,更換一個具體工廠就變得相對容易,所有的具體工廠都實現了抽象工廠中定義的那些公共介面,因此只需改變具體工廠的例項,就可以在某種程度上改變整個軟體系統的行為。抽象工廠封裝了變化,封裝了物件建立的具體細節,對客戶端隱藏物件建立的具體細節,符合"封裝變化原則"。
(2) 當一個產品族中的多個物件被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的物件。
(3) 增加新的產品族很方便,無須修改已有系統,符合“開閉原則”。
(4) 客戶端可以針對抽象進行程式設計,而不需要知道具體型別,符合"針對介面進行程式設計而不是針對具體進行程式設計原則"。
5.2.主要缺點
抽象工廠模式的主要缺點如下:
增加新的產品等級結構麻煩,需要對原有系統進行較大的修改,甚至需要修改抽象層程式碼,這顯然會帶來較大的不便,違背了“開閉原則"
5.3.抽象工廠模式具體應用
(1)根據專案的需要,可以使用Sqlserver、Access、Mysql等資料庫儲存一些物件。例如用任意一種資料庫儲存部門表、員工表。這是抽象工廠模式的一種應用,可以隨時切換資料庫進行儲存。
(2)QQ空間背景樣式,部落格背景樣式等都提供了各種風格的樣式。在Windows平臺和Linux平臺下會有不同的顯示方式。
(3)開發一個可以在Windows、Linux、Android平臺下執行的圖片閱讀器,不同平臺下有不同的顯示方式。
(4)網頁下載工具的開發: 根據需要可以下載新浪網頁、騰訊網頁、搜狐網頁等。而在不同平臺下,下載方式可能會不相同。
(5)淘寶購物最後一個支付環節,可以選擇貨到付款、網上銀行、支付寶等型別支付。在不同平臺上,各種支付的方式可能在操作上存在些差異。
(6)開發一款可以執行在Windows和Andorid平臺的射擊遊戲,Windows下有手槍、AK47、步槍、大刀等武器,Linux同樣也存在這些武器。
(7)開發火車票影象識別軟體(OCR),可以在Windows平臺和Linux平臺執行。對識別的結果可以儲存為txt、word、pdf等格式。
(8)STL裡面的集合容器List、Vector、Deque等,不管使用哪種型別的容器,都可以使用迭代進行抽象操作。
(9)生活中也有很多類似的工廠: 偉創力各個生產車間生產不同的產品; 生產海爾冰箱、海爾空調這些產品;肯德基麥當勞在全球設定各個分工廠;中國石油、紫金礦業、景德鎮陶瓷、中國移動、伊利蒙牛在全國的各個分工廠;順豐快遞、申通快遞在全國的驛站等。
相關推薦
C++設計模式——抽象工廠模式(含例項)
前言 偉創力(世界500強企業),公司有筆記本生產車間、電視機車間、空調車間、電話生產等車間,各生產車間各行其責,生產出不同型別的產品。偉創力不再是生產單一產品的企業,而是生產出多種不同型別的產品,各產品屬於不同產品等級結構中。在設計模式中,也存在一種類似的模式,可以建
設計模式——抽象工廠模式(C++實現)
concrete out png return style bsp ctp img using 1 #include <iostream> 2 #include <string> 3 4 usin
C# - 設計模式 - 抽象工廠模式
tel 總結 num provider ndb back reat param [] 抽象工廠模式 問題場景 有100個方法對Animal類型進行了引用,所以可能需要new100次Animal對象,如果總是使用new創建對象,那麽100處都會有對該對象的引用。假如今後A
重走Java設計模式——抽象工廠模式(Abstract Factory Pattern)
抽象工廠模式 抽象工廠模式是所有形態的工廠模式中最為抽象和最具一般性的一種形態。 抽象工廠模式是指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個介面,使客戶端在不必指定產品的具體的情況下,建立多個產品族中的產品物件。根據里氏替換原則,任
C#設計模式-抽象工廠模式
using System; namespace TestCS { class Program { static void Main(string[] args) { Factory factory0 = new Maserat
24種設計模式-抽象工廠模式(6)
好了,我們繼續上一節課,上一節講到女媧造人,人是造出來了,世界時熱鬧了,可是低頭一看,都是清一色的型別,缺少關愛、仇恨、喜怒哀樂等情緒,人類的生命太平淡了,女媧一想,猛然一拍腦袋,Shit!忘記給人類定義性別了,那怎麼辦?抹掉重來,然後就把人類重新洗牌,準備重新開始製造人類。
設計模式——簡單工廠模式—工廠方法模式—抽象工廠模式(比較)
一、簡單工廠模式: 簡單工廠模式是對物件建立的簡單封裝,可以通過一個工廠類來實現物件的例項化,但是這種方式如果要增加一個新的產品就要修改工廠方法,這樣就產生了工廠方法模式。二、工廠方法模式工廠方法模式能夠對產品方便的擴充套件,只需要增加新產品自己的工廠就行。三、抽
C# 設計模式----抽象工廠模式
一、引言在上一專題中介紹了工廠方法模式,工廠方法模式是為了克服簡單工廠模式的缺點而設計出來的,簡單工廠模式的工廠類隨著產品類的增加需要增加額外的程式碼),而工廠方法模式每個具體工廠類只完成單個例項的建立,所以它具有很好的可擴充套件性。但是在現實生活中,一個工廠只建立單個產品這
C++設計模式---抽象工廠模式
定義了一個建立一系列相關或相互依賴的介面,而無需制定它們的具體類。用於交換產品系列,產品的具體類名被具體工廠實現分離簡單來說就是,工廠還是兩個,可以生產A系列的產品,B系列的產品//抽象工廠模式 cla
設計模式—抽象工廠模式
elm 步驟 cli 優點 abstract 工程師 face abs ges 場景問題 舉個生活中常見的例子——組裝電腦,我們在組裝電腦的時候,通常需要選擇一系列的配件,比如CPU、硬盤、內存、主板、電源、機箱等。 需要整體考慮各個配件之間的兼容性。比如:CPU和主板,如
設計模式 - 抽象工廠模式
查看 rgs llc cli pri class print ace 分享 public interface CPU { } public class AmdCPU implements CPU{ public AmdCPU() { Syste
創造型設計模式-----抽象工廠模式
sin mage pub gin bubuko 概念 .cpp col alt 一種商品需要用多個產品組成就需要運用抽象工廠模式。 概念: 抽象工廠:聲明一個用於完成抽象商品對象創建操作的接口 具體工廠:實現創建具體產品對象的操作 抽象產品:聲明一個用於一類產品對象的接口
設計模式-抽象工廠模式
抽象工廠模式 設計模式 public class UserEntity { public int ID { get; set; } public string Name { get; set; } } public interface IUser
pyhon面向對象設計之抽象工廠模式
python 面向對象 抽象工廠模式 簡介 抽象工廠設計模式屬於創建型設計模式的一種,創建型設計模式更關註對象是如何被創建出來的。通常我們會調用對象的構造函數來創建對象實例,比如通過向類名稱傳遞相關參數來創建。但是,有時候我們會需要更加靈活的對象創建方式,這時創建型的設計模式就會大有用處了。今天
PHP設計模式 - 抽象工廠模式
抽象工廠 com 對象 creates 我們 ace {} create clas 有些情況下我們需要根據不同的選擇邏輯提供不同的構造工廠,而對於多個工廠而言需要一個統一的抽象工廠: <?php class System{} class Soft{
【設計模式】簡單工廠模式 |工廠方法模式 |抽象工廠模式
簡單工廠模式 由三種角色組成: 1、工廠類角色:是簡單工廠模式的核心,含有一定的商業邏輯和判斷邏輯。 2、抽象產品角色:一般是具體產品繼承的父類或者實現的介面。 3、具體產品角色:工廠類所建立的物件就是此角色的例項。 用一個單獨的類來做這個創在例項的過程,這就
android設計模式——抽象工廠模式
定義:為建立一組相關或者是互相以來的物件提供一個介面,而不需要指定他們的具體的類, 使用場景: 在任何需要生成複雜物件的地方,都可以使用工廠方法模式. 應用舉例: 不同牌子的汽車工廠生產不同的汽車 類圖: AbstractFactory,抽象的工廠類 Concrete
java常用設計模式--抽象工廠模式簡單例子
package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/12 11:23 * @Description:抽象工廠模式:與工廠方法模式不同的是,工廠方法模式中的工廠只生產單一的產品,而抽象工廠模式中的工廠生產多個產品。 * 還有個抽象工廠方法模式 只需要
用心理解設計模式——抽象工廠模式 (Abstract Factory Pattern)
前置文章: 用心理解設計模式——設計模式的原則 設計模式相關程式碼已統一放至 我的 Github 一、定義 建立型模式之一。 Provide an interface for creating families of
設計模式 --- 抽象工廠模式
1.定義 為建立一組相關或者相互依賴的物件提供一個介面,而不需要指定他們的具體類。 2.使用場景 一個物件族有相同的約束時可以使用抽象工廠模式。例如之前工廠方法模式的汽車組裝例子,Q3、Q5、Q7都是同一個車系,但是零部件差別很大,Q3發動機是國產的而Q7是原裝進口的,