定義:提供一個建立一系列相關或相互依賴對象的接口,而無需指定他們具體的類html
抽象工廠抽象工廠,顧名思義,就是比工廠模式更抽象的工廠模式。在工廠模式中,一個具體工廠只負責生產一個具體產品。而在抽象工廠模式中,一個具體工廠能夠生產一組相關的產品,這些產品稱爲產品族,產品族中的每個產品部分屬於每個產品繼承等級結構spa
首先咱們先了解下什麼是產品族和產品等級結構。產品等級結構即產品的繼承結構,比如一個抽象類是汽車,其子類包括奔馳,寶馬,大衆,保時捷.....這樣抽象汽車與具體汽車品牌之間構成了一個產品等級結構,抽象汽車類是父類,具體汽車類是子類。產品族,在抽象工廠模式中,產品族是指由同一個工廠生產的,屬於不一樣產品等級結構中的一組產品。如蘋果公司生產的電腦,手機,平板,手錶......構成一個產品族設計
那麼,有這兩個東西又有什麼用呢?咱們不妨思考下,在生活中,有很多工廠,每一個工廠中也生產各類不一樣的產品。咱們又如何定位到某個具體的產品呢?code
如上圖,共有15個不一樣的圖形(顏色或樣式都不同),每一行對應一個具體工廠所產生的具體產品(構成產品族),咱們只須要指明產品所處的產品族和它所屬的產品等級結構,就能夠定位到對應的產品。如第4行(第4個產品族)的第三個產品等級結構,就能夠定位到那個橢圓形htm
工廠方法模式針對的是一個產品等級結構,而抽象工廠模式面對多個產品等級結構,一個工廠等級結構負責多個不一樣的產品等級結構中的產品對象的建立。而在工廠方法模式中,一個工廠等級結構生產一個產品等級結構。上述圖中的產品若是在工廠方法模式中,須要15個具體工廠,而在抽象工廠模式中,只須要5個工廠,大大減小了工廠類的個數對象
結構:blog
在每一個OS中,都有一個圖形構建組成的構件家族,能夠經過一個抽象角色給出功能定義,而由具體子類給出不一樣OS中的具體實現,例以下兩個產品結構,分別是Button和Text,同時包含三個產品族,即Unix產品族,Linux產品族,Windows產品族,請實現該結構繼承
結構:接口
實現:get
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 }
結果:
值得注意的是,在抽象工廠模式中,增長新的產品族很容易,只須要增長具體產品並對應增長一個新的具體工廠就能夠了,對已有代碼不須要進行修改,可是增長新的產品等級結構很麻煩,須要修改全部的工廠角色,包括抽象工廠類,在全部的工廠類中都必需要添加新的產品等級結構,違背了開閉原則,這種特性被稱爲開閉原則的傾斜性