轉一篇很好的關於.net簡單工廠的設計模式

.NET設計模式(1): 簡單工廠模式

最近一直在看設計模式,想把自己的學習筆記與大家分享一下,如果能幫助大家的話,我會非常高興,同時也歡迎大家指出裏面的不足。園子裏其實關於此類文章已經很多了,如果dudu感覺放在首頁欠妥的話,可以調一下。

簡單工廠模式(Simple Factory Pattern)

介紹:簡單工廠模式不能說是一個設計模式,說它是一種編程習慣可能更恰當些。因爲它至少不是Gof23種設計模式之一。但它在實際的編程中經常被用到,而且思想也非常簡單,可以說是工廠方法模式的一個引導,所以我想有必要把它作爲第一個講一下。

引入:
我們在編程的時候,每當"new"一個對象之後,這個對象就依賴於這個類了。如果在後期的維護過程中由於某些原因需要修改一下這個類,則唯一的做法就是打開源代碼,進行修改,修改所有與這個對象有關的操作。這對我們是非常不利的。
問題出來了:對象不能應對“具體實例化類型”的變化
解決思路:套用一下李建忠李老師的話,封裝變化點,哪裏變化,封裝哪裏。在這個例子中,要實例化的類變了,就將實例化這個操作封裝起來,我們可以把"new"這個操作移交一個具體的類,由它去負責根據我們的條件創建具體類的實例,也就是下面要說的“簡單工廠模式”。

定義:
專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類或接口。簡單工廠模式又稱爲靜態工廠方法(Static Factory Method)模式,屬於類的創建型模式,通常根據一個條件(參數)來返回不同的類的實例。

意圖:
提供一個類,由它負責根據一定的條件創建某一具體類的實例

參與者:

  • 工廠角色(Creator)
    是簡單工廠模式的核心,它負責實現創建所有具體產品類的實例。工廠類可以被外界直接調用,創建所需的產品對象。
  • 抽象產品角色(Product)
    是所有具體產品角色的父類,它負責描述所有實例所共有的公共接口。
  • 具體產品角色(Concrete Product)
    繼承自抽象產品角色,一般爲多個,是簡單工廠模式的創建目標。工廠類返回的都是該角色的某一具體產品。

UML圖:
簡單工廠模式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的高內聚的責任分配原則 
  • 雖然簡單工廠模式能夠適應一定的變化,但是它所能解決的問題是遠遠有限的。它所能創建的類只能是事先教考慮到的,如果需要添加新的類,則就需要改變工廠類了。(這個問題在下一個工廠方法模式將得到很好的解決)

應用情景

  • 工廠類負責創建的對象比較少 
  • 客戶只知道傳入了工廠類的參數,對於始何創建對象(邏輯)不關心 

參考資料

  • 《深入淺出設計模式(C#/Java版) 》 清華大學出版社 
  • MSDN Webcast  C#面向對象設計模式縱橫談 李建忠老師

很好的一篇文章,很清楚明瞭解釋了簡單工廠的實現原理和思路,謝謝。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章