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);
}
四、總結
綜上所述,工廠方法模式與簡單工廠模式之間的區別就是。工廠方法模式中存在着多個子工廠,由子工廠生產具體的產品。每個工廠各司其職,不混淆,耦合性地。方便擴展。
工廠方法模式的內部關係爲: