常規的對象創建方法:
//創建一個Road對象
Road road =new Road();
new 的問題:
實現依賴,不能應對“具體實例化類型”的變化。
解決思路:
封裝變化點-----哪裡變化,封裝哪裡
潛台詞: 如果沒有變化,當然不需要額外的封裝!
工廠模式的緣起
變化點在“對象創建”,因此就封裝“對象創建”
面向接口編程----依賴接口,而非依賴實現
最簡單的解決方法:
1 class RoadFactory{
2 public static Road CreateRoad()
3 {
4 return new Road();
5 }
6 }
7 //創建一個Road對象
8 Road road=roadFactory.CreateRoad();
創建一系列相互依賴對象的創建工作:假設一個游戲開場景:
我們需要構造"道路"、"房屋"、"地道","從林"...等等對象
工廠方法如下: 1 class RoadFactory
2 {
3 public static Road CreateRoad()
4 {
5 return new Road();
6 }
7 public
0)"> static Building CreateBuilding()
8 {
9 return new Building();
10 }
11 public static Tunnel CreateTunnel()
12 {
13 return new Tunnel();
14 }
15 public static Jungle CreateJungle()
16 {
<
/span>17 return new Jungle();
18 }
19 }
調用方式如下:1 Road road = RoadFactory.CreateRoad();
3 Building building = RoadFactory.CreateBuilding();
4 Tunnel tunnel = RoadFactory.CreateTunnel();
5 Jungle jungle = RoadFactory.CreateJungle();如上可見
簡單工廠的問題: 不能應對"不同系列對象"的變化。比如有不同風格的場景---對應不同風格的道路,房屋、地道....
如何解決: 使用面向對象的技術來"封裝"變化點。
動機(Motivate): 在軟件系統中,經常面臨著"一系統相互依賴的對象"的創建工作:同時,由於需求的變化,往往存在更多系列對象的創建工作。
如何應對這種變化?如何繞過常規的對象創建方法(new),提供一種"封裝機制"來避免客戶程序和這種"多系列具體對象創建工作"的緊耦合?
意圖(Intent): 提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
----《設計模式》GOF
結構圖(Struct):
適用性:
1.一個系統要獨立於它的產品的創建、組合和表示時。
2.一個系統要由多個產品系統中的一個來配置時。
3.當你要強調一系列相關的產品對象的設計以便進行聯合使用時。
4.當你提供一個產品類庫,而只想顯示它們的接口不是實現時。
生活例子:
結構圖代碼實現:
1 abstract class AbstractFactory
2 {
3 public abstract AbstractProductA CreateProductA();
4 public abstract AbstractProductB CreateProductB();
5 }
1 abstract class AbstractProductA
2 {
3 public abstract
0)"> void Interact(AbstractProductB b);
4 }
1 abstract class AbstractProductB
2 {
3 public abstract void Interact(AbstractProductA a);
4 }
1 class ClIEnt
2 {
3 private AbstractProductA AbstractProductA;
4
0)"> private AbstractProductB AbstractProductB;
5 public ClIEnt(AbstractFactory factory)
6 {
7 AbstractProductA = factory.CreateProductA();
8 AbstractProductB = factory.CreateProductB();
9 }
10 public void Run()
11 {
12 AbstractProductB.Interact(AbstractProductA);
13 AbstractProductA.Interact(AbstractProductB);
14 }
15 }
1 class ConcreteFactory1:AbstractFactory
2 {
3 public override AbstractProductA CreateProductA()
4 {
5 return new ProductA1();
6 }
7 public override AbstractProductB CreateProductB()
8
0)"> {
9 return new ProductB1();
10 }
11 }
1 class ConcreteFactory2:AbstractFactory
2 {
3 public override AbstractProductA CreateProductA()
4 {
5 return new ProdcutA2();
6 }
7 public override AbstractProductB CreateProductB()
8 {
9 return new ProductB2();
10 }
11 }
1 class ProductA1:AbstractProductA
2 {
3 public override void Interact(AbstractProductB b)
4 {
5
0)"> Console.WriteLine(this.GetType().Name + "interact with" + b.GetType().Name);
6 }
7 }
1 class ProductB1:AbstractProductB
2 {
3 public override void Interact(AbstractProductA a)
4 {
5 Console.WriteLine(this.GetType().Name +
0)"> "interact with" + a.GetType().Name);
6 }
7 }
1 class ProdcutA2:AbstractProductA
2 {
3 public override void Interact(AbstractProductB b)
4 {
5 Console.WriteLine(this.GetType().Name + "interact with" +
0)"> b.GetType().Name);
6 }
7 }
1 class ProductB2:AbstractProductB
2 {
3 public override void Interact(AbstractProductA a)
4 {
5 Console.WriteLine(this.GetType().Name + "interact with" + a.GetType().Name);
6 }
7 }
1 public static void Main()
2 {
3 // Abstractfactory1
4 AbstractFactory factory1 = new ConcreteFactory1();
5 Client c1 = new ClIEnt(factory1);
6 c1.Run();
7 // Abstractfactory2
128)"> 8 AbstractFactory factory2 = new ConcreteFactory2();
9 Client c2 = new ClIEnt(factory2);
10 c2.Run();
11 }
Abstract Factory注意的幾點: 如果不存在”多系列對象創建“的需求變化,則沒必要應用Abstract Factory模式,靜態工廠方法足矣。
"系列對象"指的是這些對象之間有相互依賴、或作用的關系。例如游戲開發場景中的"道路"與"房屋"依賴,“道路”與“地道”的依賴。
Abstract Factory模式主要在於應對"新系列"的需求變動。其
缺點在於難以應對”新對象“的需求變動。
Abstract Factory模式經常和
Factory Method模式共同組合來應對“
對象創建”的需求變化。