程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 抽象工廠(Abstract Factory)

抽象工廠(Abstract Factory)

編輯:.NET實例教程

常規的對象創建方法:

//創建一個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         {

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模式共同組合來應對“對象創建”的需求變化。
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved