| 1. 工廠方法模式簡介1. 工廠方法模式簡介1.1 定義
工廠方法模式定義一個(gè)用于創(chuàng)建對象的接口,讓子類決定實(shí)例化哪一個(gè)類。工廠方法模式是以一個(gè)類的實(shí)例化延遲到其子類。 Factory Method模式用于在不指定待創(chuàng)建對象的具體類的情況下創(chuàng)建對象。 Factory Method模式的主要意圖是隱藏對象創(chuàng)建的復(fù)雜性。Client通常不指定要?jiǎng)?chuàng)建的具體類,Client將面向接口或抽象類進(jìn)行編碼,讓Factory類負(fù)責(zé)創(chuàng)建具體的類型。通常Factory類有一個(gè)返回抽象類或者接口的靜態(tài)方法。Client通常提供某種信息讓Factory類使用提供的信息來確定創(chuàng)建并返回哪個(gè)子類。 將創(chuàng)建子類的責(zé)任抽象出來的好處是允許Client完全無需考慮依賴類是如何創(chuàng)建的,這遵守依賴倒置原則(Dependency Inversion Principle,DIP)。Factory Method模式另外一個(gè)好處是把負(fù)責(zé)對象創(chuàng)建的代碼集中起來,如果需要修改對象生成方式,可以輕松定位并更新,而不會(huì)影響到依賴它的代碼。 在面向?qū)ο缶幊讨?,一般方法是用一個(gè)new操作符產(chǎn)生一個(gè)對象的實(shí)例。但是在一些情況下,用new操作符直接生成對象會(huì)帶來一些問題。首先,要使用new運(yùn)算符創(chuàng)建一個(gè)對象必須清楚所要?jiǎng)?chuàng)建的對象的類信息,包括類名、構(gòu)造函數(shù)等,而有時(shí)并不現(xiàn)實(shí)。其次許多類型的對象創(chuàng)建需要一系列的步驟,可能需要計(jì)算或取得對象的初始設(shè)置,選擇生成那個(gè)子對象實(shí)例,或在生成需要的對象之前必須生成一些輔助功能的對象。在這些情況下,新對象的建立就是一個(gè)過程,而不是一個(gè)簡單的操作。為輕松方便地完成復(fù)雜對象的創(chuàng)建,從而引入了工廠模式。 1.2 使用頻率
   2. 工廠方法模式結(jié)構(gòu)2.1 結(jié)構(gòu)圖
 2.2 參與者
工廠方法模式參與者: Product:Product角色,定義工廠方法所創(chuàng)建的對象的接口 ConcreteProduct:具體Product角色,實(shí)現(xiàn)Product接口 Factory ° 抽象的工廠角色,聲明工廠方法,該方法返回一個(gè)Product類型的對象 ° Factory可以定義一個(gè)工廠方法的默認(rèn)實(shí)現(xiàn),返回一個(gè)默認(rèn)的ConcreteProduct對象??梢哉{(diào)用工廠方法以創(chuàng)建一個(gè)Product對象。 ConcreteFactory:具體的工廠角色,創(chuàng)建具體Product的子工廠,重寫工廠方法以返回一個(gè)ConcreteProduct實(shí)例 3. 工廠方法模式結(jié)構(gòu)實(shí)現(xiàn)
 Product.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Structural { /// <summary> /// 定義Product抽象類,Client調(diào)用Product抽象類,并由Factory來創(chuàng)建具體類。 /// </summary> public abstract class Product { } } ConcreteProductA.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Structural { public class ConcreteProductA : Product { } } ConcreteProductB.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Structural { public class ConcreteProductB : Product { } } Factory.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Structural { public abstract class Factory { public abstract Product CreateProduct(); } } ConcreteFactoryA.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Structural { public class ConcreteFactoryA : Factory { public override Product CreateProduct() { return new ConcreteProductA(); } } } ConcreteFactoryB.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Structural { public class ConcreteFactoryB : Factory { public override Product CreateProduct() { return new ConcreteProductB(); } } } Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using DesignPatterns.FactoryMethodPattern.Structural; namespace DesignPatterns.FactoryMethodPattern { class Program { static void Main(string[] args) { Factory[] factories = new Factory[2]; factories[0] = new ConcreteFactoryA(); factories[1] = new ConcreteFactoryB(); foreach (Factory factory in factories) { Product product = factory.CreateProduct(); Console.WriteLine("Created {0}", product.GetType().Name); } } } } 運(yùn)行輸出: Created ConcreteProductA
Created ConcreteProductB
請按任意鍵繼續(xù). . .4. 工廠方法模式實(shí)踐應(yīng)用
假設(shè)你現(xiàn)在是一家KFC的管理者,要給顧客提供一系列的食品,如雞翅、雞腿等,顧客沒要求一種食品,KFC應(yīng)當(dāng)可以很快生產(chǎn)出來,采用工廠模式來實(shí)現(xiàn)這個(gè)過程。 
 KFCFood.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Practical { /// <summary> /// 抽象的KFC食品,Product角色 /// </summary> public abstract class KFCFood { public abstract void Display(); } } Chicken.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Practical { public class Chicken : KFCFood { public override void Display() { Console.WriteLine("雞腿 + 1"); } } } Wings.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Practical { public class Wings : KFCFood { public override void Display() { Console.WriteLine("雞翅 + 1"); } } } IKFCFactory.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Practical { public interface IKFCFactory { KFCFood CreateFood(); } } ChickenFactory.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Practical { public class ChickenFactory : IKFCFactory { public KFCFood CreateFood() { return new Chicken(); } } } WingsFactory.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.FactoryMethodPattern.Practical { public class WingsFactory : IKFCFactory { public KFCFood CreateFood() { return new Wings(); } } } Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using DesignPatterns.FactoryMethodPattern.Practical; namespace DesignPatterns.FactoryMethodPattern { class Program { static void Main(string[] args) { // 定義一個(gè)雞腿工廠 IKFCFactory factory = new ChickenFactory(); // 生產(chǎn)雞腿 KFCFood food1 = factory.CreateFood(); food1.Display(); // 生產(chǎn)雞腿 KFCFood food2 = factory.CreateFood(); food2.Display(); // 生產(chǎn)雞腿 KFCFood food3 = factory.CreateFood(); food3.Display(); } } } 運(yùn)行輸出: 雞腿 + 1 雞腿 + 1 雞腿 + 1 請按任意鍵繼續(xù). . . 在以上例子中,使用工廠模式的好處: 1>. 客戶端在創(chuàng)建產(chǎn)品的時(shí)候只需指定一個(gè)子工廠而無需了解該子工廠具體創(chuàng)建什么產(chǎn)品; 2>. 當(dāng)需求有變動(dòng),要不food1、food2、food3均改為“雞翅”的時(shí)候,只需將 IKFCFactory factory = new ChickenFactory();改為 IKFCFactory factory = new WingsFactory();即可; 3>. 在工廠方法模式中,核心的工廠類不是負(fù)責(zé)所有產(chǎn)品的創(chuàng)建,而是將具體的創(chuàng)建工作交給子類ConcreteFactory去做。工廠類僅僅負(fù)責(zé)給出具體工廠必須實(shí)現(xiàn)的接口,而不涉及哪一個(gè)產(chǎn)品類被實(shí)例化這種細(xì)節(jié)。工廠方法模式可以使得系統(tǒng)在不需要修改原有代碼的情況下引進(jìn)新產(chǎn)品,如現(xiàn)在要增加一種新的產(chǎn)品“薯?xiàng)l”,則無需修改原有代碼,只需增加一個(gè)“薯?xiàng)l”產(chǎn)品類和一個(gè)相應(yīng)的“薯?xiàng)l”子工廠即可。在工廠方法模式中,子工廠與產(chǎn)品類往往具有平行的等級結(jié)構(gòu),它們之間一一對應(yīng)。 5. 工廠方法模式應(yīng)用分析5.1 工廠方法模式適用情形
當(dāng)一個(gè)類不知道它所必須創(chuàng)建的對象的類信息的時(shí)候 當(dāng)一個(gè)類希望由它來指定它所創(chuàng)建的對象的時(shí)候 當(dāng)類將創(chuàng)建對象的職責(zé)委托給多個(gè)輔助子類中的某一個(gè),并且希望將哪一個(gè)輔助之類是代理者這一信息局部化的時(shí)候 5.2 工廠方法模式特點(diǎn)
使用工廠方法在一個(gè)類的內(nèi)部創(chuàng)建對象通常比直接創(chuàng)建對象更靈活 工廠方法模式通過面向?qū)ο蟮氖址ǎ瑢⑺獎(jiǎng)?chuàng)建的具體對象的創(chuàng)建工作延遲到子類,從而提供了一種擴(kuò)展的策略,較好的解決了緊耦合的關(guān)系 工廠方法模式遵守依賴倒置原則(Dependency Inversion Principle,DIP) 5.3 工廠方法模式與簡單工廠模式區(qū)別
工廠方法模式和簡單工廠模式在結(jié)構(gòu)上的不同是很明顯的。工廠方法模式的核心是一個(gè)抽象工廠類,而簡單工廠模式把核心放在一個(gè)具體工廠類上。工廠方法模式可以允許很多具體工廠類從抽象工廠類中將創(chuàng)建行為繼承下來,從而可以成為多個(gè)簡單工廠模式的綜合,進(jìn)而推廣了簡單工廠模式。 工廠方法模式退化后可以變得很像簡單工廠模式。如果非常確定一個(gè)系統(tǒng)只需要一個(gè)具體工廠類,那么就不妨把抽象工廠類合并到具體的工廠類中去。由于只有一個(gè)具體工廠類,所以不妨將工廠方法改成為靜態(tài)方法,這時(shí)候就得到了簡單工廠模式 分類: 設(shè)計(jì)模式 | 
|  |