設計模式--抽象工廠(個人筆記)
一、抽象工廠的應用場景以及優缺點
1 應用場景:
如果系統需要多套的程式碼解決方案,並且每套的程式碼解決方案中又有很多相互關聯的產品型別,並且在系統中我們可以相互替換的使用一套產品的時候可以使用該模式,客戶端不需要依賴具體的實現。
2 優點:
抽象工廠模式將產品的建立工作遲到了具體工廠的子類中,我們宣告工廠類變數的時候是使用的抽象型別,同理,我們使用產品型別也是抽象型別。
這樣做就儘可能的減少了客戶端程式碼與產品類之間的依賴,從而降低了系統的耦合度。耦合度降低了,對於後期的維護和擴充套件就更加的有利。
3 缺點:
抽象工廠模式很難支援增加新產品的變化,這是因為抽象工廠介面中已經明確了可以被建立的產品集合,如果需要新增新產品,此時就必須去修改抽象工廠的介面,
這樣就涉及到抽象工廠類的以及所有子類的變化。也就違背了“開放--封閉”原則。
4.實現要點:
1)、如果沒有應對“多系列物件建立”的需求變化,則沒有必要使用AbstractFactory模式,這時候使用簡單的靜態工廠完全可以。
2)、"系列物件"指的是這些物件之間有相互依賴、或作用的關係,例如遊戲開發場景中“道路”與“房屋”的依賴,“道路”與“地道”的依賴。
3)、AbstractFactory模式主要在於應對“新系列”的需求變動。其缺點在於難以應對“新物件”的需求變動。
4)、AbstractFactory模式經常和FactoryMethod模式共同組合來應對“物件建立”的需求變化。
二、模式的組成
1 抽象產品類角色(AbstractProduct):
為抽象工廠中相互依賴的每種產品定義抽象介面物件,
也可以這樣說,有幾種產品,就要宣告幾個抽象角色, 每一個抽象角色和一種具體的產品相匹配。
2 具體產品類(ConcreteProduct):
具體產品類實現了抽象產品類,是針對某個具體產品的實現的型別。
3 抽象工廠類角色(AbstractFactory):
定義了建立一組相互依賴的產品物件的介面操作,每種操作和每種產品一一對應。
4 具體工廠類角色(ConcreteFactory):
實現抽象類裡面的所有抽象介面操作,可以建立某系列具體的產品,這些具體的產品是“抽象產品類角色”的子類。
三、程式碼
1.基本程式碼:
public ActionResult Index() { // 哥哥的歐式風格的房子 AbstractFactory europeanFactory = new EuropeanFactory(); europeanFactory.CreateRoof().Create(); europeanFactory.CreateFloor().Create(); europeanFactory.CreateWindow().Create(); europeanFactory.CreateDoor().Create(); //弟弟的現代風格的房子 AbstractFactory modernizationFactory = new ModernizationFactory(); modernizationFactory.CreateRoof().Create(); modernizationFactory.CreateFloor().Create(); modernizationFactory.CreateWindow().Create(); modernizationFactory.CreateDoor().Create(); Console.Read(); return View(); }
/// <summary> /// 抽象工廠類,提供建立不同型別房子的介面 /// </summary> public abstract class AbstractFactory { // 抽象工廠提供建立一系列產品的介面,這裡作為例子,只給出了房頂、地板、窗戶和房門建立介面 public abstract Roof CreateRoof(); public abstract Floor CreateFloor(); public abstract Window CreateWindow(); public abstract Door CreateDoor(); } /// <summary> /// 歐式風格房子的工廠,負責建立歐式風格的房子 /// </summary> public class EuropeanFactory : AbstractFactory { // 製作歐式房頂 public override Roof CreateRoof() { string aa = "{"aa":"a1","bb":"b1"}"; string path="c:\\abc\\"; return new EuropeanRoof(); } // 製作歐式地板 public override Floor CreateFloor() { return new EuropeanFloor(); } // 製作歐式窗戶 public override Window CreateWindow() { return new EuropeanWindow(); } // 製作歐式房門 public override Door CreateDoor() { return new EuropeanDoor(); } } /// <summary> /// 現在風格房子的工廠,負責建立現代風格的房子 /// </summary> public class ModernizationFactory : AbstractFactory { // 製作現代房頂 public override Roof CreateRoof() { return new ModernizationRoof(); } // 製作現代地板 public override Floor CreateFloor() { return new ModernizationFloor(); } // 製作現代窗戶 public override Window CreateWindow() { return new ModernizationWindow(); } // 製作現代房門 public override Door CreateDoor() { return new ModernizationDoor(); } } /// <summary> /// 房頂抽象類,子類的房頂必須繼承該類 /// </summary> public abstract class Roof { /// <summary> /// 建立房頂 /// </summary> public abstract void Create(); } /// <summary> /// 地板抽象類,子類的地板必須繼承該類 /// </summary> public abstract class Floor { /// <summary> /// 建立地板 /// </summary> public abstract void Create(); } /// <summary> /// 窗戶抽象類,子類的窗戶必須繼承該類 /// </summary> public abstract class Window { /// <summary> /// 建立窗戶 /// </summary> public abstract void Create(); } /// <summary> /// 房門抽象類,子類的房門必須繼承該類 /// </summary> public abstract class Door { /// <summary> /// 建立房門 /// </summary> public abstract void Create(); } /// <summary> /// 歐式地板類 /// </summary> public class EuropeanFloor : Floor { public override void Create() { Console.WriteLine("建立歐式的地板"); } } /// <summary> /// 歐式的房頂 /// </summary> public class EuropeanRoof : Roof { public override void Create() { Console.WriteLine("建立歐式的房頂"); } } /// <summary> ///歐式的窗戶 /// </summary> public class EuropeanWindow : Window { public override void Create() { Console.WriteLine("建立歐式的窗戶"); } } /// <summary> /// 歐式的房門 /// </summary> public class EuropeanDoor : Door { public override void Create() { Console.WriteLine("建立歐式的房門"); } } /// <summary> /// 現代的房頂 /// </summary> public class ModernizationRoof : Roof { public override void Create() { Console.WriteLine("建立現代的房頂"); } } /// <summary> /// 現代的地板 /// </summary> public class ModernizationFloor : Floor { public override void Create() { Console.WriteLine("建立現代的地板"); } } /// <summary> /// 現代的窗戶 /// </summary> public class ModernizationWindow : Window { public override void Create() { Console.WriteLine("建立現代的窗戶"); } } /// <summary> /// 現代的房門 /// </summary> public class ModernizationDoor : Door { public override void Create() { Console.WriteLine("建立現代的房門"); } }
2.擴充套件程式碼:
新建一套古典風格的房子:
/// <summary> ///先為表弟的房子來建立一個工廠類吧 /// </summary> public class ClassicalFactory : AbstractFactory { //建立房頂 public override Roof CreateRoof() { return new ClassicalRoof(); } // 建立地板 public override Floor CreateFloor() { return new ClassicalFloor(); } // 建立窗戶 public override Window CreateWindow() { return new ClassicalWindow(); } // 建立房門 public override Door CreateDoor() { return new ClassicalDoor(); } } /// <summary> ///古典的房頂 /// </summary> public class ClassicalRoof : Roof { public override void Create() { Console.WriteLine("建立古典的房頂"); } } /// <summary> /// 古典的地板 /// </summary> public class ClassicalFloor : Floor { public override void Create() { Console.WriteLine("建立古典的地板"); } } /// <summary> /// 古典的窗戶 /// </summary> public class ClassicalWindow : Window { public override void Create() { Console.WriteLine("建立古典的窗戶"); } } /// <summary> /// 古典的房門 /// </summary> public class ClassicalDoor: Door { public override void Create() { Console.WriteLine("建立古典的房門"); } }
此時,只需要新增五個類:一個是古典風格工廠類,負責建立古典風格的房子,另外幾個類是具有古典風格的房頂、地板、窗戶和房門的具體產品。
從上面程式碼看出,抽象工廠對於系列產品的變化支援 “開放——封閉”原則(指的是要求系統對擴充套件開放,對修改封 閉),擴充套件起來非常簡便,
但是,抽象工廠對於增加新產品這種情況就不支援”開放——封閉 “原則,因為要修改建立系列產品的抽象基類 AbstractFactory,增加相應產品的建立方法,這也是抽象工廠的缺點所在。
說明:此文章純屬個人筆記,加深記憶,原博主連結:http://www.cnblogs.com/PatrickLiu/p/7596897.html