設計模式培訓之四:策略模式
查看本人文章索引請通過http://www.rzrgm.cn/seesea125/archive/2012/04/17/2453256.html
一、定義
策略模式定義了一系列的算法,并將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立于使用它的客戶而獨立變化。
二、概述
應用場景:
1、 多個類只區別在表現行為不同,可以使用Strategy模式,在運行時動態選擇具體要執行的行為。
2、 需要在不同情況下使用不同的策略(算法),或者策略還可能在未來用其它方式來實現。
3、 對客戶隱藏具體策略(算法)的實現細節,彼此完全獨立。
三、代碼實現
需求:商場收費系統,根據商品的單價和數量,得出的總結可以"正常收費", "打八折","滿300返100", "打七折", "打五折"等等。
代碼如下:
abstract class CashSuper { public abstract double acceptCash(double money); } //正常收費子類 class CashNormal : CashSuper { public override double acceptCash(double money) { return money; } } //打折收費子類 class CashRebate : CashSuper { private double moneyRebate = 1d; public CashRebate(string moneyRebate) { this.moneyRebate = double.Parse(moneyRebate); } public override double acceptCash(double money) { return money*moneyRebate; } } //返利收費子類 class CashReturn : CashSuper { private double moneyCondition = 0.0d; private double moneyReturn = 0.0d; public CashReturn (string moneyCondition,string moneyReturn) { this.moneyCondition=double.Parse(moneyCondition); this.moneyReturn=double.Parse(moneyReturn); } public override double acceptCash(double money) { double result = money; if (money >= moneyCondition) result = money - Math.Floor(money / moneyCondition) * moneyReturn; return result; } }
Context類:
class CashContext { private CashSuper cs; public CashContext(string type) { switch (type) { case "正常收費": CashNormal cs0=new CashNormal(); cs=cs0; break; case "滿300返100": CashReturn cr1 = new CashReturn("300","100"); cs = cr1; break; case "打八折": CashRebate cr2 = new CashRebate("0.8"); cs = cr2; break; } } public double GetResult(double money) { return cs.acceptCash(money); } }
客戶端調用:
CashContext csuper = new CashContext(cbxType.SelectedItem.ToString()); double totalPrices = 0d; totalPrices = csuper.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
四、和工廠的區別:
上面代碼也可以用工廠方法實現,不過策略和工廠的區別很大。
如果用工廠實現,核心工廠是這樣的,其他地方代碼不變:
class CashFactory { public static CashSuper createCashAccept(string type) { CashSuper cs = null; switch (type) { case "正常收費": cs = new CashNormal(); break; case "滿300返100": cs = new CashReturn("300", "100"); break; case "打八折": cs = new CashRebate("0.8"); break; } return cs; } }
使用工廠的時候,客戶端調用
CashSuper csuper = CashFactory.createCashAccept(cbxType.SelectedItem.ToString());
double totalPrices = 0d; //工廠模式解決方案 totalPrices = csuper.acceptCash(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
可見兩種實現,他們代碼很類似,大概的只是多了一個方法
public double GetResult(double money) { return cs.acceptCash(money); }
由此可見他們的區別:他們返回的內容不同,工廠是返回不同的實例給客戶端,而策略的實例只是為了自己的類使用,他是根據參數返回算法的結果GetResult,因此他們區別是目的不同,一個是為了返回實例,一個是為了封裝不同的算法,適應算法的變化。


浙公網安備 33010602011771號