抽象工廠模式概述 定義:提供一個創建一系列相關或相互依賴對象的介面,而無需指定他們具體的類 抽象工廠抽象工廠,顧名思義,就是比工廠模式更抽象的工廠模式。在工廠模式中,一個具體工廠只負責生產一個具體產品。而在抽象工廠模式中,一個具體工廠可以生產一組相關的產品,這些產品稱為產品族,產品族中的每一個產品部 ...
- 抽象工廠模式概述
定義:提供一個創建一系列相關或相互依賴對象的介面,而無需指定他們具體的類
抽象工廠抽象工廠,顧名思義,就是比工廠模式更抽象的工廠模式。在工廠模式中,一個具體工廠只負責生產一個具體產品。而在抽象工廠模式中,一個具體工廠可以生產一組相關的產品,這些產品稱為產品族,產品族中的每一個產品部分屬於每一個產品繼承等級結構
首先我們先瞭解下什麼是產品族和產品等級結構。產品等級結構即產品的繼承結構,好比一個抽象類是汽車,其子類包括賓士,寶馬,大眾,保時捷.....這樣抽象汽車與具體汽車品牌之間構成了一個產品等級結構,抽象汽車類是父類,具體汽車類是子類。產品族,在抽象工廠模式中,產品族是指由同一個工廠生產的,屬於不同產品等級結構中的一組產品。如蘋果公司生產的電腦,手機,平板,手錶......構成一個產品族
那麼,有這兩個東西又有什麼用呢?我們不妨思考下,在生活中,有不少工廠,每個工廠中也生產各種不同的產品。我們又如何定位到某個具體的產品呢?
如上圖,共有15個不同的圖形(顏色或樣式都不一樣),每一行對應一個具體工廠所產生的具體產品(構成產品族),我們只需要指明產品所處的產品族和它所屬的產品等級結構,就可以定位到對應的產品。如第4行(第4個產品族)的第三個產品等級結構,就可以定位到那個橢圓形
- 與工廠方法模式的區別
工廠方法模式針對的是一個產品等級結構,而抽象工廠模式面對多個產品等級結構,一個工廠等級結構負責多個不同的產品等級結構中的產品對象的創建。而在工廠方法模式中,一個工廠等級結構生產一個產品等級結構。上述圖中的產品如果在工廠方法模式中,需要15個具體工廠,而在抽象工廠模式中,只需要5個工廠,大大減少了工廠類的個數
- 抽象工廠模式的實現
結構:
- AbstractFactory(抽象工廠):聲明瞭一組用於創建一族產品的方法,每個方法對應一個產品
- ConcreteFactory(具體工廠):實現在抽象工廠中聲明的創建產品的方法,生成具體產品,構成產品族
- AbstractProduct(抽象產品):為每種產品聲明介面,它聲明瞭產品具有的業務方法
- ConcreteProduct(具體產品):定義具體產品的具體生產對象,實現抽象介面中聲明的業務方法
- 抽象工廠模式應用實例
在每個OS中,都有一個圖形構建組成的構件家族,可以通過一個抽象角色給出功能定義,而由具體子類給出不同OS中的具體實現,例如下兩個產品結構,分別是Button和Text,同時包含三個產品族,即Unix產品族,Linux產品族,Windows產品族,請實現該結構
結構:
實現:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace AbstractFactory 7 { 8 9 interface ComponentFactory//抽象工廠介面 10 { 11 Button CreateButton(); 12 Text CreateText(); 13 } 14 15 public interface Button//抽象按鈕產品介面 16 { 17 void Display(); 18 } 19 public interface Text//抽象文本產品介面 20 { 21 void Display(); 22 } 23 24 public class WindowsButton : Button //具體Windows產品 25 { 26 public void Display() 27 { 28 Console.WriteLine("創建Window Button"); 29 } 30 } 31 32 public class WindowsText : Text 33 { 34 public void Display() 35 { 36 Console.WriteLine("創建Window Text"); 37 } 38 } 39 40 public class LinuxButton : Button//具體Linux產品 41 { 42 public void Display() 43 { 44 Console.WriteLine("創建Linux Button"); 45 } 46 } 47 48 public class LinuxText : Text 49 { 50 public void Display() 51 { 52 Console.WriteLine("創建Linux Text"); 53 } 54 } 55 56 public class UnixButton : Button//具體Unix產品 57 { 58 public void Display() 59 { 60 Console.WriteLine("創建Unix Button"); 61 } 62 } 63 64 public class UnixText : Text 65 { 66 public void Display() 67 { 68 Console.WriteLine("創建Unix Text"); 69 } 70 } 71 72 public class WindowsFactory : ComponentFactory//具體Windows控制項工廠 73 { 74 public Button CreateButton() 75 { 76 return new WindowsButton(); 77 } 78 79 public Text CreateText() 80 { 81 return new WindowsText(); 82 } 83 } 84 85 public class LinuxFactory : ComponentFactory//具體Linux控制項工廠 86 { 87 public Button CreateButton() 88 { 89 return new LinuxButton(); 90 } 91 92 public Text CreateText() 93 { 94 return new LinuxText(); 95 } 96 } 97 98 public class UnixFactory : ComponentFactory//具體Unix控制項工廠 99 { 100 public Button CreateButton() 101 { 102 return new UnixButton(); 103 } 104 105 public Text CreateText() 106 { 107 return new UnixText(); 108 } 109 } 110 111 class Program 112 { 113 static void Main(string[] args) 114 { 115 ComponentFactory comfactory; 116 Button button; 117 Text text; 118 //也可通過配置文件存儲具體工廠名 119 comfactory = new WindowsFactory(); 120 button = comfactory.CreateButton(); 121 button.Display(); 122 123 comfactory = new LinuxFactory(); 124 button = comfactory.CreateButton(); 125 button.Display(); 126 127 comfactory = new UnixFactory(); 128 text = comfactory.CreateText(); 129 text.Display(); 130 131 } 132 } 133 } 134 }
結果:
值得註意的是,在抽象工廠模式中,增加新的產品族很容易,只需要增加具體產品並對應增加一個新的具體工廠就可以了,對已有代碼不需要進行修改,但是增加新的產品等級結構很麻煩,需要修改所有的工廠角色,包括抽象工廠類,在所有的工廠類中都必須要添加新的產品等級結構,違背了開閉原則,這種特性被稱為開閉原則的傾斜性
- 抽象工廠模式的優缺點和適用環境
- 抽象工廠模式的優點:
- 隔離了具體類的生成,使得客戶端不需要知道什麼被創建
- 當一個產品族的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族的對象
- 抽象工廠模式增加新的產品族很容易,無需修改已有系統,符合開閉原則
- 抽象工廠模式的缺點
- 增加新的產品結構很麻煩,需要對原有系統進行大規模的修改,甚至需要修改抽象層代碼,違背了開閉原則
- 抽象工廠模式的適用環境
- 當一個系統不依賴於產品類實例如何被創建、組合和表達的細節,用戶無需關心對象的創建過程,將對象的創建和適用解耦
- 系統中有多於一個的產品族,但每次只需要使用其中某一個產品族,可以通過配置文件等動態地改變產品族,也很方便的增加新的產品族
- 屬於同一個產品族的產品將一起使用
- 產品等級結構穩定,設計完成後,不會向系統增加i新的產品等級結構或者刪除已有的產品等級結構