在做一件事情完成一項任務時,往往會有很多個方法,這每一種方法都可以被稱為策略,我們會根據不同的環境或條件,從眾多方法中選取一個合適的方法來完成這件事情或任務。就像我們過年回家,回家的方式有很多種,比如坐飛機、乘坐火車、坐客車、走路等等,但是由於自身條件限制或者環境限制,我們往往會選擇一個比較適合自己的回家方式回家。而我們選用的這個方法就可以稱之為策略。 其實所謂的策略模式,是一種對象行為型模式,它定義了算法家族,然後分別對算法封裝,讓算法之間可以相互替換。這個模式讓算法的變化,不會影響到使用算法的客戶。它也被稱之為政策模式。 策略模式的結構圖: Strategy類: 為Context定義了一系列的可以被重用的算法或者行為。 ConcreteStrategy類: 具體策略類,它封裝了具體的算法或行為,繼承Strategy類,有助於析取出這些算法中的公共功能。 策略模式應用舉例: 代碼結構圖: 窗體設計圖: 代碼實現: [csharp] double total = 0.0d; private void btnOK_Click(object sender, EventArgs e) { CashContext csuper = new CashContext(cmbType.SelectedItem.ToString()); double totalPrices = 0d; totalPrices = csuper . GetResult (Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text)); total = total + totalPrices; listBox1.Items.Add("單價:" + txtPrice.Text + "數量:" + txtNum.Text + "合計:" + totalPrices.ToString()); lblTotal.Text =Convert .ToString ( total) ; } private void btnRef_Click(object sender, EventArgs e) { txtPrice.Text = ""; txtNum.Text = ""; listBox1.Text = ""; lblTotal.Text = ""; } private void Form1_Load(object sender, EventArgs e) { cmbType.Items .AddRange (new object []{"正常收費","打八折","打七折","打五折","滿300返100"}); cmbType.SelectedIndex = 0; } } class CashContext { CashSuper cs = null; public CashContext(string type)//string type不是具體的收費策略,而是一個字符串,表示收費類型 { switch (type ) { case "正常收費": CashNormal cs0 = new CashNormal(); cs = cs0; break; case "滿300返100": CashReturn cs1 = new CashReturn("300","100"); cs = cs1; break; case "打八折": CashRebate cs2 = new CashRebate("0.8"); cs = cs2; break; } } public double GetResult(double money) { return cs.acceptCash(money); } } 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 - moneyReturn; return result; } } 策略模式的適用: 第一:如果一個系統中有很多類,而他們的區別也只是在於他們的行為,這時就可以使用策略模式從眾多行為中選取其中一種行為。 第二:一個系統需要動態的從多種算法中選取某一種算法。 第三:系統有復雜的、與算法相關的數據結構,而我們又不希望客戶端的客戶知道這些數據結構,在具體策略中封裝算法和相關數據結構,以確保算法的安全性,對算法保密。 第四:當不同的行為堆放在一個類中,就難免在執行時,會使用條件語句來選擇某一種合適的行為。 策略模式的優點: 第一:簡化了單元測試,每個算法都有自己的類,可以通過自己的接口來單獨測試。 第二:可以避免使用多重條件轉移語句,使之易維護。 第三:策略模式定義了一系列算法行為,所有算法完成的都是相同工作,只是實現不同,它可以以相同方式調用所有算法,減少各種與使用算法類之間的耦合。