C#設計模式四(工廠方法模式)

C#設計模式之工廠方法模式

一、引言

在前面我們介紹到關於簡單工廠設計模式的一些講解。那麼本篇章主要講解工廠方法模式。但從字面上來看,簡單工廠模式和工廠模式都是基於工廠思想的。那麼兩者之間自然存在着一定的相似。

先來回顧一下簡單工廠模式的原理:
在這裏插入圖片描述

由上圖可知,簡單工廠模式中,
其中共有七個(或更多)的產品,這些產品符合一定的標準規範,及所有產品都是繼承同一個類。
這樣可以使所有產品具有同一類型的模板。實現基本類似的功能。
工廠類Operate中有一個switch語句,這個選擇語句可以根據用戶的指定來實例化7個(或更多)產品中的一個。其餘沒有選擇的產品不會實例化,防止資源浪費。

所以簡單工廠模式的核心就是選擇性實例化對象。如下:

public class OperationFactory
{
    public static Operation createOperate(string operate)  //工廠內含有一個選擇性分支
    {
        Operation oper = null;
        switch (operate)  //根據用戶輸入的字符串來選擇新建的產品(類)
        {
            case "+":
                {
                    oper = new OperationAdd();  //返回產品(加類的對象)
                    break;
                }
            case "-":
                {
                    oper = new OperationSub();  //返回產品(減類的對象)
                    break;
                }
            case "*":
                {
                    oper = new OperationMul();  //返回產品(乘類的對象)
                    break;
                }
            case "/":
                {
                    oper = new OperationDiv();  //返回產品(除類的對象)
                    break;
                }
            case "sqr":
                {
                    oper = new OperationSqr();  //返回產品(平方類的對象)
                    break;
                }
            case "sqrt":
                {
                    oper = new OperationSqrt();  //返回產品(開方類的對象)
                    break;
                }
            case "+/-":
                {
                    oper = new OperationReverse();//返回產品(相反數類的對象)
                    break;
                }
        }

        return oper;  //將最終選擇的返回
    }
}

那麼工廠方法類和簡單工廠類又什麼區別呢?下面我們正式介紹

二、工廠方法模式和簡單工廠模式不同

工廠方法模式將簡單工廠模式中的switch語句中的分支全部變成了工廠子類,讓其新建產品放到具體工廠子類中去。這個概念有點像是,將不同的產品放到不同的子工廠裏去生成。然後通過選擇哪個子工廠即選擇了相應的產品了。例如一個家電工廠分爲洗衣機工廠分部、冰箱工廠分部、熱水器工廠分部。那麼用戶在選擇熱水器的話,就必須指定熱水器工廠分部,讓其進行熱水器的生產。這樣做能夠將責任細化。而簡單工廠模式中,因爲只有一個工廠,所以無論什麼產品都在同一個工廠中生產。所以工廠方法模式比簡單工廠模式更加的細化,大大降低了耦合程度。

三、工廠方法模式的實現

與簡單工廠模式相比,工廠方法模式主要不同點在於工廠中的選擇部分。

//產品接口類

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;
    }
}
class OperationMul : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA * NumberB;
        return result;
    }
}
class OperationDiv : Operation
{
    public override double GetResult()
    {
        double result = 0;
        if (NumberB == 0)
            throw new Exception("除數不能爲0。");
        result = NumberA / NumberB;
        return result;
    }
}
class OperationSqr : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberB * NumberB;
        return result;
    }
}
class OperationSqrt : Operation
{
    public override double GetResult()
    {
        double result = 0;
        if (NumberB < 0)
            throw new Exception("負數不能開平方根。");
        result = Math.Sqrt(NumberB);
        return result;
    }
}
class OperationReverse : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = -NumberB;
        return result;
    }
}

//工廠接口類,工廠規範

/// <summary>
/// 工廠標準規範/"接口",所有的子工廠必須繼承它以便統一規範
/// </summary>
public abstract class Factory   
{
    public abstract Operation CreateOperation();
}

//具體子工廠類

public class FactoryAdd:Factory
{
    public override Operation CreateOperation()
    {
        return new OperationAdd();
    }

}
public class FactorySub : Factory
{
    public override Operation CreateOperation()
    {
        return new OperationSub();
    }

}
public class FactoryMul : Factory
{
    public override Operation CreateOperation()
    {
        return new OperationMul();
    }

}
public class FactoryDiv : Factory
{
    public override Operation CreateOperation()
    {
        return new OperationDiv();
    }

}
public class FactorySqr : Factory
{
    public override Operation CreateOperation()
    {
        return new OperationSqr();
    }

}
public class FactorySqrt : Factory
{
    public override Operation CreateOperation()
    {
        return new OperationSqrt();
    }

}
public class FactoryReverse : Factory
{
    public override Operation CreateOperation()
    {
        return new OperationReverse();
    }

}

//用戶端

/*簡單工廠的特點:
* 只有一個工廠
* 一個工廠只生產一種產品       
*/
/*工廠方法的特點
* 有多個子工廠
* 每個工廠各司其職,只生產屬於自己的產品
* 將不同的產品劃分,有較低的耦合度 
*/
static void Main(string[] args)
{
try
{
    Console.Write("請輸入數字A:");
    string strNumberA = Console.ReadLine();
    Console.Write("請選擇運算符號(+、-、*、/):");
    string strOperate = Console.ReadLine();
    Console.Write("請輸入數字B:");
    string strNumberB = Console.ReadLine();
    string strResult = "";
    
    Factory fac = null;
    switch (strOperate)   //通過選擇分支選擇具體的子工廠
    {
        case "+":
                fac = new FactoryAdd();  //返回產品
                break;
        case "-":
                fac = new FactorySub();  //返回產品
                break;
        case "*":
                fac = new FactoryMul();  //返回產品
                break;
        case "/":
                fac = new FactoryDiv();  //返回產品
                break;
        case "sqr":
                fac = new FactorySqr();  //返回產品
                break;
        case "sqrt":
                fac = new FactorySqrt();  //返回產品
                break;
        case "+/-":
                fac = new FactoryReverse();//返回產品
                break;
    }
    Operation oper=fac.CreateOperation();              //調用子工廠的方法來進行創建產品類
    oper.NumberA = Convert.ToDouble(strNumberA);       //將選好的類的數值A賦值
    oper.NumberB = Convert.ToDouble(strNumberB);       //將選好的類的數值B賦值
    strResult = oper.GetResult().ToString();           //訪問選好類中的方法返回操作結果
    Console.WriteLine("結果是:" + strResult);
    Console.ReadLine();
}
catch (Exception ex)
{
    Console.WriteLine("您的輸入有錯:" + ex.Message);
}

四、總結

綜上所述,工廠方法模式與簡單工廠模式之間的區別就是。工廠方法模式中存在着多個子工廠,由子工廠生產具體的產品。每個工廠各司其職,不混淆,耦合性地。方便擴展。

工廠方法模式的內部關係爲:

在這裏插入圖片描述

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