1. 程式人生 > >C#工廠模式

C#工廠模式

最近一直在看設計模式,想把自己的學習筆記與大家分享一下,如果能幫助大家的話,我會非常高興,同時也歡迎大家指出裡面的不足。園子裡其實關於此類文章已經很多了,如果dudu感覺放在首頁欠妥的話,可以調一下。
簡單工廠模式(Simple Factory Pattern)
介紹:簡單工廠模式不能說是一個設計模式,說它是一種程式設計習慣可能更恰當些。因為它至少不是Gof23種設計模式之一。但它在實際的程式設計中經常被用到,而且思想也非常簡單,可以說是工廠方法模式的一個引導,所以我想有必要把它作為第一個講一下。
引入:
我們在程式設計的時候,每當"new"一個物件之後,這個物件就依賴於這個類了。如果在後期的維護過程中由於某些原因需要修改一下這個類,則唯一的做法就是開啟原始碼,進行修改,修改所有與這個物件有關的操作。這對我們是非常不利的。
問題出來了:物件不能應對“具體例項化型別”的變化
解決思路:套用一下李建忠李老師的話,封裝變化點,哪裡變化,封裝哪裡。在這個例子中,要例項化的類變了,就將例項化這個操作封裝起來,我們可以把"

new"這個操作移交一個具體的類,由它去負責根據我們的條件建立具體類的例項,也就是下面要說的“簡單工廠模式”。
定義:
專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類或介面。簡單工廠模式又稱為靜態工廠方法(Static Factory Method)模式,屬於類的建立型模式,通常根據一個條件(引數)來返回不同的類的例項。
意圖:
提供一個類,由它負責根據一定的條件建立某一具體類的例項
參與者: 

· 工廠角色(Creator)
是簡單工廠模式的核心,它負責實現建立所有具體產品類的例項。工廠類可以被外界直接呼叫,建立所需的產品物件。 

· 抽象產品角色(Product)
是所有具體產品角色的父類,它負責描述所有例項所共有的公共介面。 

· 具體產品角色(Concrete Product)
繼承自抽象產品角色,一般為多個,是簡單工廠模式的建立目標。工廠類返回的都是該角色的某一具體產品。 

UML圖:


現實生活中例子:
每次參加不同的聚會或者與不同的人見面,可能穿的衣服是不一樣的,比如,你今天上午要與你的一個新客戶見面,你可能會對你的老婆說:老婆,給拿件商務裝(引數),我要去見我的一個客戶,你老婆(工廠類)接到你的請求(商務裝引數)後,從衣櫃中取出一件商務裝(具體產品),交給你。整個過程就完成了。
分析:
你可能根據不同的條件,要的衣服是不一樣的,但要的衣服都是已經在你的衣櫃中存在的。並且,每件上衣它們都屬於同一種抽象,即它們可以從一個抽象類或介面 中繼承,這此衣服各自都有一定特徵,這些都是條件。然後你要的時候,就可以向你老婆說一種特徵,她就會根據這個特徵為你服務了。這就是典型的簡單工廠模式 的應用。
 抽象產品類程式碼

1      /// <summary>
2    /// 抽象產品類:上衣
3    /// </summary>
4    public interface ICoat
5    {
6        void GetYourCoat();
7    } 


非常簡單,是吧?這裡我只是舉一個僅僅能說明問題的例子,在具體的專案中,可能是很複雜的哦。。
具體產品類程式碼

1namespace SimpleFactory
 2{
 3    /// <summary>
 4    /// 具體產品類:商務上衣
 5    /// </summary>
 6    public class BusinessCoat:ICoat
 7    {
 8        public void GetYourCoat()
 9        {
10            Console.WriteLine("商務上衣");
11        }
12    }
13
14    /// <summary>
15    /// 具體產品類:時尚上衣
16    /// </summary>
17    public class FashionCoat : ICoat
18    {
19        /// <summary>
20        /// 實現ICoat中定義的方法
21        /// </summary>
22        /// <returns></returns>
23        public void GetYourCoat()
24        {
25            Console.WriteLine("時尚上衣");
26        }
27    }
28}
     簡單工廠模式中最核心的部分:工廠類

1namespace SimpleFactory
 2{
 3    /// <summary>
 4    /// 簡單工廠模式中的核心部分:工廠類
 5    /// </summary>
 6    public class Factory
 7    {
 8        public ICoat CreateCoat(string styleName)
 9        {
10            switch (styleName.Trim().ToLower())
11            {
12                case "business":
13                    return new BusinessCoat();
14                case "fashion":
15                    return new FashionCoat();
16                default :
17                    throw new Exception("還沒有你要的那種衣服");
18            }
19        }
20    }
21}
再看一下客戶在呼叫的時候的程式碼

 1 /// <summary>
 2    /// 客戶類
 3    /// </summary>
 4    class Client
 5    {
 6        static void Main(string[] args)
 7        {
 8            ICoat food;
 9            try
10            {
11                Factory factory = new Factory();
12
13                Console.Write("我要的是時尚上衣\t");
14                food = factory.CreateCoat("fashion");
15                food.GetYourCoat();
16
17            }
18            catch (Exception ex)
19            {
20                Console.WriteLine(ex.Message);
21            }
22        }
23    }


到這裡,程式碼就完成了。
在客戶端的程式碼中有我們就可以根據具體的引數,返回我們希望返回的物件,將"new"操作推遲到工廠類中實現。
這裡,引數我直接寫上了,我們其實可以將這個引數寫到一個xml檔案中,如app.config檔案中,動態的讀出來,需要穿另外一種衣服了,只需要開啟 app.config檔案,修改裡面的值就行了,不需要專案重新編譯。這樣這個小程式就能夠適應一定的變化了(在上傳上去的程式碼中我會修改一下)。其實它 也是設計模式正要解決的問題,在不修改程式碼的情況下,使專案能夠適應一定的客戶需求變化。注意,是一定的,並非全部。

   優點:

· 簡單工廠模式能夠根據外界給定的資訊,決定究竟應該建立哪個具體類的物件。通過它,外界可以從直接建立具體產品對  象的尷尬局面中擺脫出來。 

· 外界與具體類隔離開來,偶合性低。 

· 明確區分了各自的職責和權力,有利於整個軟體體系結構的優化。 

缺點:

· 工廠類集中了所有例項的建立邏輯,容易違反GRASPR的高內聚的責任分配原則  

· 雖然簡單工廠模式能夠適應一定的變化,但是它所能解決的問題是遠遠有限的。它所能建立的類只能是事先教考慮到的,如果需要新增新的類,則就需要改變工廠類了。(這個問題在下一個工廠方法模式將得到很好的解決) 

應用情景

· 工廠類負責建立的物件比較少  

· 客戶只知道傳入了工廠類的引數,對於始何建立物件(邏輯)不關心  

介紹:
簡單工廠模式中,我們提到,工廠方法模式是簡單工廠模式的一個延伸,它屬於Gof23中設計模式的建立型設計模式。它解決的仍然是軟體設計中與建立物件有關的問題。它可以更好的處理客戶的需求變化。
工廠方法模式(Factory Method Pattern)
引入
我們繼續來說"new"的問題,我們在簡單工廠模式中, 將例項化物件的工作推遲到了專門負責建立物件的工廠類中,這樣,在我們事先預知的情況下,可以根據我們的需要動態建立產品類。但是,我們的預知是有限的, 客戶的變化可能是無限的。所以,就出現了問題,一旦客戶的變化超越了我們的預知,我們就必須修改我們的原始碼了。這是設計模式所不允許的,怎麼辦呢?工廠 方法模式正是解決此類問題的。
問題:具體工廠類的建立工作不能滿足我們的要求了,建立的工作變化了
解決思路:哪裡變化,封裝哪裡。把具體工廠封裝起來。

定義
工廠方法模式又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多型工廠模式(Polymorphic Factory),在工廠方法模式中,父類負責定義建立物件的公共介面,而子類則負責生成具體的物件,這樣做的目的是將類的例項化操作延遲到子類中完成, 即由子類來決定究竟應該例項化(建立)哪一個類。

意圖
定義一個使用者建立物件的介面,讓子類決定例項化哪一個類,工廠方法模式使一個類的例項化延遲到其子類。

參與者

· 抽象產品角色(Product)
定義產品的介面 

· 具體產品角色(ConcreteProduct) 
實現介面Product的具體產品類 

· 抽象工廠角色(Creator) 
宣告工廠方法(FactoryMethod),返回一個產品 

· 真實的工廠(ConcreteCreator)
實現FactoryMethod工廠方法,由客戶呼叫,返回一個產品的例項 

工廠方法模式UML圖


現實生活中的例子
為了方便大家理解,我仍然舉穿衣服方面的一個例子。這個例子與簡單工廠模式中的那個例子有些不同。
據說清朝有個皇帝穿衣非常的奢侈,每種衣服(具體產品類)由一宮女(具體工廠類)專門負責,這樣一來,每增加一種衣服(具體產品類),就要多出一個宮女(具體工廠類),但是他們各負其責,互不影響。皇帝之所以這樣做,是因為針對穿衣服這件事來說,可擴充套件性是非常強的()。

分析
實現的功能:可以根據皇帝的要求,動態的建立(由宮女去拿)已存在的具體產品(衣服),如果皇帝的要求太苛刻,這種衣服還沒有,只需要 增加一個宮女,一個衣服就能夠滿足他的要求了。每個宮女只負責一種衣服(高內聚),要增加一種衣服,對於以前的所有宮女與衣服來說,都不會受到影響(設計 模式中所期望的)。說到這裡,是不是明白了工廠方法模式所能解決的問題及其應用了?呵呵。。你一定在想,比簡單工廠模式靈活性高吧。。

抽象工廠角色程式碼

1namespace FactoryMethod
 2{
 3    /// <summary>
 4    /// 抽象工廠類,定義產品的介面
 5    /// </summary>
 6    public interface IFactory
 7    {
 8        ICoat CreateCoat();
 9    }
10}

抽象產品角色程式碼

1namespace FactoryMethod
 2{
 3    /// <summary>
 4    /// 抽象產品類
 5    /// </summary>
 6    public interface ICoat
 7    {
 8        void ShowCoat();
 9    }
10}

具體工廠角色程式碼

1namespace FactoryMethod
 2{
 3    /// <summary>
 4    /// 具體工廠類:用於建立商務上衣類
 5    /// </summary>
 6    public class BusinessFactory:IFactory
 7    {        
 8        public ICoat CreateCoat()
 9        {
10            return new BusinessCoat();
11         }
12    }
13
14    /// <summary>
15    /// 具體工廠類,用於建立時尚上衣
16    /// </summary>
17    public class FashionFactory : IFactory
18    {
19        public ICoat CreateCoat()
20        {
21            return new FashionCoat();
22        }
23    }
24}

具體產品角色程式碼

1namespace FactoryMethod
 2{
 3    /// <summary>
 4    /// 具體產品類,商務上衣類
 5    /// </summary>
 6    public class BusinessCoat:ICoat
 7    {
 8        public void ShowCoat()
 9        {
10            Console.WriteLine("這件是商務上衣");
11        }
12    }
13
14    /// <summary>
15    /// 具體產品類,時尚上衣類
16    /// </summary>
17    public class FashionCoat : ICoat
18    {
19        public void ShowCoat()
20        {
21            Console.WriteLine("這件是時尚上衣");
22        }
23    }
24}
25

客戶端程式碼

1namespace FactoryMethod
 2{
 3    /// <summary>
 4    /// 客戶端程式碼
 5    /// </summary>
 6    class Client
 7    {
 8        static void Main(string[] args)
 9        {
10            //為了方便以後修改,將工廠類的類名寫在應用程式配置檔案中
11            string factoryName = ConfigurationManager.AppSettings["FactoryName"];
12          
13            IFactory factory = (IFactory)Assembly.Load("ConcreteFactory").CreateInstance("FactoryMethod." + factoryName);
14            
15            ICoat coat = factory.CreateCoat();
16            //顯示你要的上衣
17            coat.ShowCoat();
18        }
19    }
20}

客戶端程式碼需要注意的兩個地方:
1,把具體工廠類類名稱寫在了應用程式配置檔案中,方便修改
2,用到了反射,利用.NET提供的反射可以根據類名來建立它的例項,非常方便


由反射想到的:
下面這一段內容不是計劃要寫的。
如果在具體工廠中,每次new的物件都是一個,而且這些類是繼承自抽象產品介面的,那麼我們用簡單工廠模式也 可以實現動態的增加具體產品類。這樣來做,在簡單工廠模式中最核心的部分----工廠類不要根據傳來的條件去動態建立產品類,利用反射機制去建立。把要例項化的類名放在應用程式配置檔案中,呵呵。。這樣利用.NET特有的反射就可以用簡單工廠模式解決更多的問題了,工廠方法模式的一部分問題也是可以通過 “這樣的簡單工廠模式”解決的,在需要增加具體產品類時,不用增加具體工廠,是不是簡單一些呀。下去試一下。。。

優點:

· 基於工廠角色和產品角色的多型性設計是工廠方法模式的關鍵。它能夠使工廠可以自主確定建立何種產品物件。而且如何建立一個具體產品的細節完全封裝在具體工廠內部,符合高內聚,低耦合。 

· 在系統中加入新產品時,無需修改抽象工廠和抽象產品提供的介面,無需修改客戶端,也無需修改其他的具體工廠和具體產品,很好的利用了封裝和委託。 

缺點: 

· 在新增新產品時,需要編寫新的具體產品類(其實這不算一個缺點,因為這是不可避免的),要增加與之對應的具體工廠類。 

應用情景: 

· 類不知道自己要建立哪一個物件時 

· 類用它的子類來指定建立哪個物件 

· 當類將建立物件的職責委託給多個幫助子類中的某一個,並且你希望將哪一個幫助子類是代理者這一資訊區域性化的時候   

工廠方法模式在ASP.NET HTTP通道中的應用,TerryLee在他的那篇檔案中寫的非常好,推薦去看一下。

抽象工廠模式(Abstract Factory Pattern)

引入:
在前面介紹的兩個建立型模式裡面,我們解決的都是有關"new"的問題,用它們來避免顯式指定類建立物件。我寫的也非常簡單易懂,相信看過的朋友們都應該對簡單工廠模式工廠方法模式的意圖、所能解決的問題及適用情景有一定的瞭解了。但是若要達到靈活運用,什麼時候用,怎樣用合適還不是看一篇文章就能解決的問題。呵呵..這需要你對OO的理解程度,你的專案開發經驗等等許多方面的積累。一起努力喔。。
好了,咱們言歸正傳,通過對這兩個模式的瞭解,我們掌握一種思想,就是在建立一個物件時,需要把容易發生變化的地方給封裝起來,來控制變化(哪裡變化,封 裝哪裡),以適應客戶的變動,專案的擴充套件。但是,我們在軟體系統中,經常面臨著“一系列相互依賴的物件”的建立工作,同時由於需求的變化,這“一系列相互 依賴的物件”也要改變,如何應對這種變化呢?如何像簡單工廠模式工廠方法模式一樣繞過常規的"new",然後提供一種“封裝機制”來避免客戶程式和這種“多系列具體物件建立工作”的緊耦合?可能有人會說,你也可以將這些物件一個一個通過工廠方法模式來 解決呀?但是,我們試想,既然是一系列相互依賴的物件,它們是有聯絡的,每個物件都這樣解決,你又如何來保證他們的聯絡呢?舉一個例子:Windows桌 面主題,當你更換一個桌面主題的時候,系統的開始按鈕、工作列、選單欄、工具欄等等都變了,而且是一起變的,他們的色調都還很一致,難道類似這樣的問題, 怎麼來解決呢?它的天敵就是抽象工廠模式。

意圖:
提供一個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類。

參考者:
也就是該模式中的各個類或物件之間的關係:

· 抽象工廠(Abstract Factory)
宣告生成一系列抽象產品的方法 

· 具體工廠(Concrete Factory)
執行生成一系列抽象產品的方法,生成一系列具體的產品 

· 抽象產品(Abstract Product)
為這一系列的某一種產品宣告介面 

· 具體產品(Product)
定義具體工廠生成的具體產品的物件,實現產品介面 

· 客戶(Client)
我們的應用程式客戶端(不要理解成人),使用抽象產品和抽象工廠生成物件。 

 抽象工廠模式UML圖


抽象工廠模式在生活中的例項
咱們繼續拿怎麼穿衣服來說明這個抽象工廠模式。
就拿你來說吧。工作了,為了參加一些聚會,肯定有兩套或多套衣服吧,比如說有商務裝(成套,一系列具體產品)、時尚裝(成套,一系列具體產品),甚至對於一個家庭來說,可能有商務女裝、商務男裝、時尚女裝、時尚男裝,這些也都是成套的,即一系列具體產品。咱們假設一種情況(現實中是不存在的,要不然,沒法進入共產主義了,但有利於說明抽象工廠模式),在你的家中,某一個衣櫃(具體工廠)只能存放某一種這樣的衣服(成套,一系列具體產品),每次拿這種成套的衣服時也自然要從這個衣櫃中取出了。用OO的思想去理解,所有的衣櫃(具體工廠)都是衣櫃類的(抽象工廠)某一個,而每一件成套的衣服又包括具體的上衣(某一具體產品),褲子(某一具體產品),這些具體的上衣其實也都是上衣(抽象產品),具體的褲子也都是褲子(另一個抽象產品)。

分析:
要好好去讀上面那個例項,雖然有點繞嘴,其實只要用心去讀,分清了抽象工廠模式的各個角色,對理解設計模式是非常重要的。理解頭緒,然後接合簡單工廠模式、工廠方法模式對工廠家族的瞭解,再加上抽象工廠模式的意圖,頭腦中差不多有一個雛型了吧。好了,咱們一起來分析一下。。
先把各個角色揪出來。
抽象工廠:虛擬的衣櫃,它只是個概念而已。在專案中可能是一個介面或抽象類,定義規則,取出上衣,褲子。
具體工廠:具體的存在的衣櫃,它用於存放某一種成套的衣服,換句話說,這種成套的衣服都是從這個衣櫃中取出的。在專案中繼承於抽象工廠,實現抽象工廠中的方法,取出具體產品,某一件上衣,某一條褲子。
抽象產品:虛擬的衣服,也只是個概念。在專案中可能是多個介面或抽象類,定義規則,有什麼特性,起什麼作用。
具體產品:具體的實際存在的產品,它指的就是用於組裝成某一套衣服的某一件上衣或褲子。它繼承自某一個抽象產品。實
              現抽象產品中制定的規則,特性。
它們之間怎麼聯絡呢?客戶在用的時候,依賴的又是什麼呢?
客戶在要的時候,首先要說出你要的什麼系列的衣服,然後根據它的要求生成一個具體工廠的例項,剩下的工作就都是這個倒黴的具體工廠了,它會根據自己的實現 生成一個上衣,生成一個褲子,然後把它交給客戶。客戶在這一過程中並不知道具體工廠都做了什麼。也就是說,客戶只依賴於抽象工廠和抽象產品了。在初始化的 時候會用到一次具體工廠類名,我們根據.NET特有的反射機制又可以把這個在客戶端唯一的具體的非抽象類放到一個應用程式配置檔案中,防止它變化。


具體程式碼如下:
抽象工廠角色:

1namespace AbstractFactory
 2{
 3    //抽象工廠類,
 4    public abstract class AbstractClothes
 5    {
 6        //抽象方法:建立一個上衣
 7        abstract public AbstractCoat CreateCoat();
 8        //抽象方法:建立一個褲子
 9        abstract public AbstractTrousers CreateTrousers();
10    }
11}
12


抽象產品角色:

 1namespace AbstractFactory
 2{
 3    /// <summary>
 4    /// 抽象產品----上衣抽象類
 5    /// </summary>
 6    public abstract class AbstractCoat
 7    {
 8        //性別屬性
 9        public abstract bool Sex
10        {
11            get;
12        }
13
14        //樣式屬性
15        public abstract string Style
16        {
17            get;
18        }
19    }
20
21    /// <summary>
22    /// 抽象產品----褲子抽象類
23    /// </summary>
24    public abstract class AbstractTrousers
25    {
26        //性別屬性
27        public abstract bool Sex
28        {
29            get;
30        }
31
32        //樣式屬性
33        public abstract string Style
34        {
35            get;
36        }
37    }
38}
39


具體工廠角色:

 1namespace AbstractFactory
 2{
 3    /// <summary>
 4    ///時尚男裝 
 5    /// </summary>
 6    public class FashionManClothes:AbstractClothes
 7    {
 8        public override AbstractFactory.AbstractCoat CreateCoat()
 9        {
10            return new CoatA();
11        }
12
13        public override AbstractTrousers CreateTrousers()
14        {
15            return new TrousersA();
16        }
17    }
18
19    /// <summary>
20    /// 時尚女裝
21    /// </summary>
22    public class FashionWomanClothes : AbstractClothes
23    {
24        public override AbstractCoat CreateCoat()
25        {
26            return new CoatB();
27            //throw new Exception("The method or operation is not implemented.");
28        }
29        public override AbstractTrousers CreateTrousers()
30        {
31            return new TrousersB();
32            //throw new Exception("The method or operation is not implemented.");
33        }
34    }
35}


具體產品角色:(注意:我並沒有把所有的具體產品類都列出來,由於簡單,可以推想出剩餘的產品類,詳見附件)

1namespace AbstractFactory
 2{
 3    /// <summary>
 4    /// 時尚男性上衣
 5    /// </summary>
 6    public class CoatA:AbstractFactory.AbstractCoat
 7    {
 8        private bool sex = true;
 9        private string style = "時尚";
10        /// <summary>
11        /// 重寫基類的Sex屬性
12        /// </summary>
13        public override bool Sex
14        {
15            get
16            {
17                return sex;
18            }            
19        }
20        
21        /// <summary>
22        /// 重寫基類的Style屬性
23        /// </summary>
24        public override string Style
25        {
26            get
27            {
28                return style;
29            }            
30        }
31    }
32
33    /// <summary>
34    /// 時尚男性褲子
35    /// </summary>
36    public class TrousersA : AbstractTrousers
37    {
38        private bool sex = true;
39        private string style = "時尚";
40        public override bool Sex
41        {
42            get
43            {
44                return sex;
45            }
46        }
47        public override string Style
48        {
49            get
50            {
51                return style;
52            }
53        }
54    }
55}


客戶端程式碼:

 1namespace AbstractFactory
 2{
 3    /// <summary>
 4    /// 建立衣服類
 5    /// </summary>
 6    public class CreateClothes
 7    {
 8        private AbstractCoat myCoat;
 9        private AbstractTrousers myTrousers;
10        public CreateClothes(AbstractClothes clothes)
11        {
12            myCoat = clothes.CreateCoat();
13            myTrousers = clothes.CreateTrousers();
14        }
15
16        public void ShowMyClothes()
17        {
18            Console.WriteLine("My Clothes:");
19            string sex= myCoat.Sex ? "男" : "女";
20            //Console.WriteLine("Coat:{0} {1}", myCoat.Sex ? "男" : "女", myCoat.Style);
21            Console.WriteLine("Coat:{0} {1}", sex, myCoat.Style);
22            sex=myTrousers.Sex?"男":"女";
23            Console.WriteLine("Trousers:{0} {1}", sex, myTrousers.Style);
24        }
25    }  
26
27
28    public class Client
29    {
30        static void Main(string[] args)
31        {
32            //建立一個工廠類的例項   
33            string assemblyName = ConfigurationManager.AppSettings["assemblyName"];
34            string fullTypeName =string.Concat( ConfigurationManager.AppSettings["nameSpaceName"] ,".", ConfigurationManager.AppSettings["typename"]);
35
36            AbstractClothes factory = (AbstractClothes)Assembly.Load(assemblyName).CreateInstance(fullTypeName);
37            CreateClothes clothes = new CreateClothes(factory);
38            clothes.ShowMyClothes();
39            Console.Read();
40        }        
41    }
42}
43


app.config檔案

1<configuration>
2  <appSettings>
3    <!--一般情況下只需改第三個"typename"就行了,具體工廠類    -->
4    <add key="assemblyName" value="ConcreteFactory"/>
5    <add key="nameSpaceName" value="AbstractFactory"/>
6    <add key="typename" value="FashionManClothes"/>
7  </appSettings>
8</configuration>


這樣,程式碼就完成了。

小結一下:
抽象工廠模式堪稱gof23種設計模式精典模式之一,它能夠解決諸如:通過顯示指定類建立物件,緊耦合,對物件表示或實現的依賴等等一些問題,有關設計模式的設計原則,所能解決的問題,詳見OO與設計模式的原則、目標 。
抽象工廠模式適用於對“一系列相互依賴的物件”的建立工作,這些物件是相互依賴的,是有聯絡的。如果僅為一個物件的建立則用簡單工廠模式工廠方法模式完全可以實現,沒有必要用抽象工廠模式。
由於抽象工廠模式的客戶端只依賴於抽象工廠,抽象產品,在初始化過程中僅用到一次具體工廠我們又把它放在了app.config中了,完全依賴介面,這樣 不僅在系統的擴充套件性方面好,而且可以提高團隊開發效率。兩個團隊只要彼此瞭解定義的介面,抽象類,可以並行開發。舉個例子,就拿部落格園來說吧,我們在用自 己的部落格空間時,可以隨時的換面板,這個換面板是不是典型的抽象工廠模式嗎?如果是,它的各個角色又是什麼呢?我認為是的。換一下面板,你部落格頁面上的各 個樣式都變了,而且這裡各個樣式都同屬於你選定的這一個面板。而每個樣式都又是獨立的,它們組合起來就成了一款面板。我們來揪出來各個角色。
抽象工廠:面板
抽象產品:樣式
具體工廠:某一款面板,面板名即為具體工廠的類名
具體產品:某一個樣式。
雖然不存在這樣的介面與類,但是它確實是抽象工廠模式的一個應用。抽象工廠制定都有哪些樣式名,而具體工廠來實現這些樣式名中的樣式,而具體工廠中用到的各個樣式都是一個具體產品。這也是我的理解,如兄弟們有不同的見解,歡迎發表意見,共同探討。
確定過各個角色之後,就可以說一下為什麼提高效率了。不論dudu在設計部落格園時用什麼工具或語言,它與瀘江部落格只要約定好所有用到的樣式名就可以了。而瀘江部落格就可以根據要求單獨去做每一款面板了。

優點: 

· 隔離了具體類的生成,客戶不需要知道怎樣生成了每一個具體產品,什麼時間生成的。它將客戶與具體的類分離,依賴於抽象類,耦合性低。 

· 一個產品族中的多個物件被設計成一起工作,它能夠保證客戶端始終只使用一個產品族中的物件。這對一些需要根據當前環境來決定其行為的軟體系統來說,是非常實用的一種設計模式。  

· 它有利於更換產品系列,由於客戶端只依賴於抽象類,具體類也被寫到應用程式配置檔案中,更換產品系列時,只須更改一下具體工廠名就行了。 

缺點:

· 難以支援新種類的產品。難以擴充套件抽象工廠以生產新種類的產品。這是因為抽象工廠幾口確定了可以被建立的產品集合,支援新種類的產品就需要擴充套件該工廠介面,這將涉及抽象工廠類及其所有子類的改變。 

應用情景:

· 同一個產品族的產品在一起使用時,而且它們之間是相互依賴的,不可分離 

· 系統需要由相互關聯的多個物件來構成 

· 你想提供一組物件而不顯示它們的實現過程,只顯示它們的介面 

· 系統不應當依賴某一些具體產品類。 

應用場景舉例:

· 遊戲開發中的多風格系列場景 

· 系統更改面板 

· 支援多種觀感標準的使用者介面工具箱(Kit)。