1. 程式人生 > >04.設計模式_抽象工廠模式

04.設計模式_抽象工廠模式

實例 chang .html 子類 代碼 消費 ring 模式 喜歡

轉載自 http://www.cnblogs.com/zhili/p/AbstractFactory.html

一、引言

在上一專題中介紹了工廠方法模式,工廠方法模式是為了克服簡單工廠模式的缺點而設計出來的,簡單工廠模式的工廠類隨著產品類的增加需要增加額外的代碼),而工廠方法模式每個具體工廠類只完成單個實例的創建,所以它具有很好的可擴展性。但是在現實生活中,一個工廠只創建單個產品這樣的例子很少,因為現在的工廠都多元化了,一個工廠創建一系列的產品,如果我們要設計這樣的系統時,工廠方法模式顯然在這裏不適用,然後抽象工廠模式卻可以很好地解決一系列產品創建的問題,這是本專題所要介紹的內容。

二、抽象工廠詳細介紹

這裏首先以一個生活中抽象工廠的例子來實現一個抽象工廠,然後再給出抽象工廠的定義和UML圖來幫助大家更好地掌握抽象工廠模式,同時大家在理解的時候,可以對照抽象工廠生活中例子的實現和它的定義來加深抽象工廠的UML圖理解。

2.1 抽象工廠的具體實現

下面就以生活中 “絕味” 連鎖店的例子來實現一個抽象工廠模式。例如,絕味鴨脖想在江西南昌和上海開分店,但是由於當地人的口味不一樣,在南昌的所有絕味的東西會做的辣一點,而上海不喜歡吃辣的,所以上海的所有絕味的東西都不會做的像南昌的那樣辣,然而這點不同導致南昌絕味工廠和上海的絕味工廠生成所有絕味的產品都不同,也就是某個具體工廠需要負責一系列產品(指的是絕味所有食物)的創建工作,下面就具體看看如何使用抽象工廠模式來實現這種情況。

/// <summary>
    /// 下面以絕味鴨脖連鎖店為例子演示下抽象工廠模式
    /// 因為每個地方的喜歡的口味不一樣,有些地方喜歡辣點的,有些地方喜歡吃不辣點
    /// 客戶端調用
    /// </summary>
    class Client
    {
        static void Main(string[] args)
        {
            // 南昌工廠制作南昌的鴨脖和鴨架
            AbstractFactory nanChangFactory = new NanChangFactory();
            YaBo nanChangYabo 
= nanChangFactory.CreateYaBo(); nanChangYabo.Print(); YaJia nanChangYajia= nanChangFactory.CreateYaJia(); nanChangYajia.Print(); // 上海工廠制作上海的鴨脖和鴨架 AbstractFactory shangHaiFactory = new ShangHaiFactory(); shangHaiFactory.CreateYaBo().Print(); shangHaiFactory.CreateYaJia().Print(); Console.Read(); } } /// <summary> /// 抽象工廠類,提供創建兩個不同地方的鴨架和鴨脖的接口 /// </summary> public abstract class AbstractFactory { // 抽象工廠提供創建一系列產品的接口,這裏作為例子,只給出了絕味中鴨脖和鴨架的創建接口 public abstract YaBo CreateYaBo(); public abstract YaJia CreateYaJia(); } /// <summary> /// 南昌絕味工廠負責制作南昌的鴨脖和鴨架 /// </summary> public class NanChangFactory : AbstractFactory { // 制作南昌鴨脖 public override YaBo CreateYaBo() { return new NanChangYaBo(); } // 制作南昌鴨架 public override YaJia CreateYaJia() { return new NanChangYaJia(); } } /// <summary> /// 上海絕味工廠負責制作上海的鴨脖和鴨架 /// </summary> public class ShangHaiFactory : AbstractFactory { // 制作上海鴨脖 public override YaBo CreateYaBo() { return new ShangHaiYaBo(); } // 制作上海鴨架 public override YaJia CreateYaJia() { return new ShangHaiYaJia(); } } /// <summary> /// 鴨脖抽象類,供每個地方的鴨脖類繼承 /// </summary> public abstract class YaBo { /// <summary> /// 打印方法,用於輸出信息 /// </summary> public abstract void Print(); } /// <summary> /// 鴨架抽象類,供每個地方的鴨架類繼承 /// </summary> public abstract class YaJia { /// <summary> /// 打印方法,用於輸出信息 /// </summary> public abstract void Print(); } /// <summary> /// 南昌的鴨脖類,因為江西人喜歡吃辣的,所以南昌的鴨脖稍微會比上海做的辣 /// </summary> public class NanChangYaBo : YaBo { public override void Print() { Console.WriteLine("南昌的鴨脖"); } } /// <summary> /// 上海的鴨脖沒有南昌的鴨脖做的辣 /// </summary> public class ShangHaiYaBo : YaBo { public override void Print() { Console.WriteLine("上海的鴨脖"); } } /// <summary> /// 南昌的鴨架 /// </summary> public class NanChangYaJia : YaJia { public override void Print() { Console.WriteLine("南昌的鴨架子"); } } /// <summary> /// 上海的鴨架 /// </summary> public class ShangHaiYaJia : YaJia { public override void Print() { Console.WriteLine("上海的鴨架子"); } }

2.2 抽象工廠模式的定義和類圖

上面代碼中都有詳細的註釋,這裏就不再解釋上面的代碼了,下面就具體看看抽象工廠模式的定義吧(理解定義可以參考上面的實現來加深理解):

抽象工廠模式:提供一個創建產品的接口來負責創建相關或依賴的對象,而不具體明確指定具體類

抽象工廠允許客戶使用抽象的接口來創建一組相關產品,而不需要知道或關心實際生產出的具體產品是什麽。這樣客戶就可以從具體產品中被解耦。下面通過抽象工模式的類圖來了解各個類中之間的關系:

技術分享

2.3 抽象工廠應對需求變更

看完上面抽象工廠的實現之後,如果 “絕味”公司又想在湖南開一家分店怎麽辦呢? 因為湖南人喜歡吃麻辣的,下面就具體看看應用了抽象工廠模式的系統是如何應對這種需求的。

/// <summary>
    /// 如果絕味又想開一家湖南的分店時,因為湖南喜歡吃麻的
    /// 所以這是有需要有一家湖南的工廠專門制作
    /// </summary>
    public class HuNanFactory : AbstractFactory
    {
        // 制作湖南鴨脖
        public override YaBo CreateYaBo()
        {
            return new HuNanYaBo();
        }

        // 制作湖南鴨架
        public override YaJia CreateYaJia()
        {
            return new HuNanYajia();
        }
    }

    /// <summary>
    /// 湖南的鴨脖
    /// </summary>
    public class HuNanYaBo : YaBo
    {
        public override void Print()
        {
            Console.WriteLine("湖南的鴨脖");
        }
    }

    /// <summary>
    /// 湖南的鴨架
    /// </summary>
    public class HuNanYajia : YaJia
    {
        public override void Print()
        {
            Console.WriteLine("湖南的鴨架子");
        }
    }

此時,只需要添加三個類:一個是湖南具體工廠類,負責創建湖南口味的鴨脖和鴨架,另外兩個類是具有湖南口味的鴨脖類和鴨架類。從上面代碼看出,抽象工廠對於系列產品的變化支持 “開放——封閉”原則(指的是要求系統對擴展開放,對修改封閉),擴展起來非常簡便,但是,抽象工廠對於添加新產品這種情況就不支持”開放——封閉 “原則,這也是抽象工廠的缺點所在,這點會在第四部分詳細介紹。

三、抽象工廠的分析

抽象工廠模式將具體產品的創建延遲到具體工廠的子類中,這樣將對象的創建封裝起來,可以減少客戶端與具體產品類之間的依賴,從而使系統耦合度低,這樣更有利於後期的維護和擴展,這真是抽象工廠模式的優點所在,然後抽象模式同時也存在不足的地方。下面就具體看下抽象工廠的缺點(缺點其實在前面的介紹中以已經涉及了):

抽象工廠模式很難支持新種類產品的變化。這是因為抽象工廠接口中已經確定了可以被創建的產品集合,如果需要添加新產品,此時就必須去修改抽象工廠的接口,這樣就涉及到抽象工廠類的以及所有子類的改變,這樣也就違背了“開發——封閉”原則。

知道了抽象工廠的優缺點之後,也就能很好地把握什麽情況下考慮使用抽象工廠模式了,下面就具體看看使用抽象工廠模式的系統應該符合那幾個前提:

  • 一個系統不要求依賴產品類實例如何被創建、組合和表達的表達,這點也是所有工廠模式應用的前提。
  • 這個系統有多個系列產品,而系統中只消費其中某一系列產品
  • 系統要求提供一個產品類的庫,所有產品以同樣的接口出現,客戶端不需要依賴具體實現。

五、總結

到這裏,抽象工廠模式的介紹就結束,在下一專題就將為大家介紹建造模式。

04.設計模式_抽象工廠模式