簡單工廠模式與工廠方法模式

工廠模式

工廠模式是創建模式,主要是爲創建對象提供過渡接口 ,以便將創建對象的具體過程屏蔽隔離起來,達到提高靈活性的目的。
工廠模式在《深入淺出設計模式》和《大話設計模式》中分爲三類:

  • 簡單工廠模式(Simple Factory)
  • 工廠方法模式(Factory Factory)
  • 抽象工廠模式(Abstract Factory)

這三種模式從上到下逐步抽象,並且更具有一般性。
我剛開始看着《大話設計模式》學習,抽象工廠還沒看到,所以這一篇就先記一下前兩種,後面看到了再更新。。。

簡單工廠模式

簡單工廠模式又稱爲靜態工廠方法模式,它其實不是23種設計模式之一,只是工廠模式的簡單版本(嗯,看名字就知道了)。我的理解,簡單地說,它就是用一個單獨的類來進行創建實例這個過程。

簡單工廠模式的組成有:

  • 工廠類角色,它是這個模式的核心,包含一定的判斷邏輯。
  • 抽象產品角色,它是具體產品所繼承的父類或實現的接口。
  • 具體產品角色,這纔是使用模式要創建的具體實例的類。

類圖如下:
這裏寫圖片描述
借《大話設計模式》中的例子,展示一下模式的應用。
語言:C#
編譯環境:Mac MonoDevelop
要求:實現一個計算器的功能。
計算器有不同的運算符(+、-、*、/),這些運算符都有一個共同的特點:使用兩個操作數,然後得出運算結果,因此我們可以寫出運算基類。

public class Operation
{
    private double _numberA = 0;
    private double _numberB = 0;

    public double NumberA
    {
        get { return _numberA; }
        set { _numberA = value; }
    }
    public double NumberB
    {
        get { return _numberB; }
        set { _numberB = value; }
    }
    public virtual double GetResult()
    {
        double result = 0;
        return result;
    }
}

接下來,寫出繼承自運算類的加法類、減法類等。

class OperationAdd : Operation 
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA + NumberB;
        return result;
    }
}

class OperationSub : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA - NumberB;
        return result;
    }
}

乘法類、除法類同理可以實現。
接下來是關鍵的工廠類,根據傳入的參數的不同,動態地決定實例化哪個類。

public class OperationFactory
{
    public static Operation createOperate(string operate)
    {
        Operation oper = null;
        switch (operate) {
        case "+":
            oper = new OperationAdd ();
            break;
        case "-":
            oper = new OperationSub ();
            break;
        }
        return oper;
    }
}

最後是客戶端的實現。

Operation oper;
oper = OperationFactory.createOperate ("+");
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult ();
Console.WriteLine ("result = " + result.ToString());

這樣就完成了簡單工廠模式,如果後面要增加其他運算,比如乘方、正弦等,只需要增加相應的運算子類,然後在工廠類裏增加判斷即可。

寫到這裏,大家大概可以看出簡單工廠的優缺點了。
優點:
工廠類含有必要的判斷邏輯,可以決定在什麼時候創建哪一個產品類的實例,客戶端可以免除直接創建產品對象的責任,而僅僅”消費”產品。簡單工廠模式通過這種做法實現了對責任的分割。
缺點:
1) 當產品有複雜的多層等級結構時,工廠類只有自己,以不變應萬變,就是模式的缺點。因爲工廠類集中了所有產品創建邏輯,一旦不能正常工作,整個系統都要受到影響。
2) 系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,有可能造成工廠邏輯過於複雜,而且違背了開閉原則。
3) 簡單工廠模式通常使用靜態工廠方法,這使得無法由子類繼承,造成工廠角色無法形成基於繼承的等級結構。
工廠方法模式就可以很好地解決這種擴展的侷限性。

工廠方法模式

工廠方法模式,定義一個用於創建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。
工廠方法模式的結構:

  • 抽象工廠角色 ,這是工廠方法模式的核心,它與應用程序無關,是具體工廠角色必須實現的接口或必須繼承的父類。
  • 具體工廠角色,具體實現創建對象的過程。
  • 抽象產品角色,具體產品繼承的父類或實現的接口。
  • 具體產品角色,具體工廠所創建的對象就是這個。

類圖如下:
這裏寫圖片描述

接下來,看看如何用工廠方法模式改造上面的例子。

// 這是一個工廠類的接口
interface IFactory
{
    Operation CreateOperation();
}

// 以下是各個工廠子類,需要實現工廠接口
class AddFactory : IFactory 
{
    // 在不同的子類中返回不同的產品實例
    public Operation CreateOperation(){
        return new OperationAdd();
    }
}

class SubFactory : IFactory 
{
    public Operation CreateOperation(){
        return new OperationSub();
    }
}

接下來是客戶端的實現:

IFactory operFactory = new AddFactory();
Operation oper = operFactory.CreateOperation ();
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult ();
Console.WriteLine ("result = " + result.ToString());

工廠方法模式克服了簡單工廠違背開閉原則的缺點,又保持了封裝對象創建過程的優點。但缺點是每加一個產品,就需要增加一個產品工廠的類。簡單工廠的判斷是在工廠類裏,工廠方法模式其實是把判斷移到了客戶端。不過,C#的反射機制可以解決分支判斷的問題。嗯,後面再說。

發佈了23 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章