如何將實例化具體類的代碼從應用中抽離,或者封裝起來,使他們不會干擾到應用的其他部分?
1 interface IAnimal 2 { 3 void Shout(); 4 } 5 6 class Dog:IAnimal 7 { 8 #region IAnimal 成員 9 10 public void Shout() 11 { 12 Console.WriteLine("汪汪汪..."); 13 } 14 15 #endregion 16 } 17 18 class Duck:IAnimal 19 { 20 #region IAnimal 成員 21 22 public void Shout() 23 { 24 Console.WriteLine("嘎嘎嘎..."); 25 } 26 27 #endregion 28 }
1 class AnimalFactory 2 { 3 //靜態工廠方法 4 public static IAnimal Create(string category) 5 { 6 IAnimal animal = null; 7 switch (category) 8 { 9 case "Dog": 10 animal = new Dog(); 11 break; 12 case "Duck": 13 animal = new Duck(); 14 break; 15 default: 16 break; 17 } 18 return animal; 19 } 20 }
把具體實例化的過程封裝了起來,這已經開始有了面向對象編程的意識了(雖然這裡用的是靜態方法)。
接著上面的例子,我們把動物種類進行抽象,不再讓他通同switch判斷,下面我們創建動物類的工廠
1 public interface AnimalFactory 2 { 3 IAnimal Create(); 4 } 5 6 class DogFactory:AnimalFactory 7 { 8 #region AnimalFactory 成員 9 10 public IAnimal Create() 11 { 12 return new Dog(); 13 } 14 15 #endregion 16 } 17 18 class DuckFactory:AnimalFactory 19 { 20 #region AnimalFactory 成員 21 22 public IAnimal Create() 23 { 24 return new Duck(); 25 } 26 27 #endregion 28 }
1 public interface IAnimal 2 { 3 void Shout(); 4 } 5 6 class Duck:IAnimal 7 { 8 #region IAnimal 成員 9 10 public void Shout() 11 { 12 Console.WriteLine("嘎嘎嘎..."); 13 } 14 15 #endregion 16 } 17 18 class Dog : IAnimal 19 { 20 #region IAnimal 成員 21 22 public void Shout() 23 { 24 Console.WriteLine("汪汪汪..."); 25 } 26 27 #endregion 28 }
如果我們這時候再添加各種類型的動物因為不用再去大肆修改原來的代碼,直接再建立新的動物工廠就行,這不就是實現類設計原則中常說的開放-封閉原則麼。
這個也是我們比較常見的一個模式,還記得Petshop這個案例麼,它裡面就有用到,在數據訪問層就是用到的抽象工廠,創建了MSSQL和oracle數據庫對數據操作的工廠。
通過工廠去創建對應數據類的處理。關於Petshop大家感興趣的話可以自己去下載下來看,我們再寫一個動物的例子好了。假設上面的動物分為家養和野生兩種類型
1 //家養 2 public interface IKeepAnimal 3 { 4 void Shout(); 5 } 6 //野生 7 public interface IWildAnimal 8 { 9 void Shout(); 10 }
分別實現這兩個接口
1 class KeepDog:IKeepAnimal 2 { 3 #region IKeepAnimal 成員 4 5 public void Shout() 6 { 7 Console.WriteLine("家養狗,汪!汪!汪!"); 8 } 9 10 #endregion 11 } 12 13 class WildDog:IWildAnimal 14 { 15 #region IWildAnimal 成員 16 17 public void Shout() 18 { 19 Console.WriteLine("野狗,汪~~~"); 20 } 21 22 #endregion 23 }
創建抽象工廠;依賴抽象,而不是依賴具體。
1 interface AnimalFactory 2 { 3 IKeepAnimal KeepFactory(); 4 IWildAnimal WildFactory(); 5 } 6 7 class DogFacory:AnimalFactory 8 { 9 #region AnimalFactory 成員 10 11 public IKeepAnimal KeepFactory() 12 { 13 return new KeepDog(); 14 } 15 16 public IWildAnimal WildFactory() 17 { 18 return new WildDog(); 19 } 20 21 #endregion 22 }
鴨子的實現方式也和狗的一樣,大家感興趣的話可以試著自己去寫下。
工廠方法模式通過讓子類決定創建的對象是什麼,來達到將對象創建的過程封裝的目的。
抽象工廠模式提供一個接口,用於創建相關或依賴的對象家族,而不需要明確指定哪個類。