定義:面試
策略模式定義了一系列的算法,並將每個算法封裝起來,並且使它們還能夠相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。算法
一、 提供了一種替代繼承的方法,並且既保持了繼承的優勢(代碼重用),還比繼承更靈活(算法獨立,能夠任意擴展);ide
二、 避免程序中使用多重條件轉移語句,使系統更靈活,並易於擴展;函數
三、 遵照大部分GRASP原則和經常使用設計原則,高內聚、低偶合;單元測試
四、 易於進行單元測試,各個算法區分開,能夠針對每一個算法進行單元測試;測試
五、 ……ui
一、 由於每一個具體策略類都會產生一個新類,因此會增長系統須要維護的類的數量;this
二、 選擇何種算法須要客戶端來建立對象,增長了耦合,這裏能夠經過與工廠模式結合解決該問題;spa
三、 程序複雜化。.net
舉例 1:
有一個同窗去公司面試,同窗技術很好,因此他被公司錄用了。可是在一個月事後,發工資的日子到了。他發現公司給他的工資發少了。因而他找財務理論,財務告訴他,工資並無少。由於他的工資是扣除公積金、稅和保險後的實際工資。但他當初和老闆談的時候是不扣稅、公積金和保險的,他很鬱悶。因而和老闆大吵了一架,離開了公司。這是一個真實的故事,我之因此用這個例子是由於他確實符合咱們的策略模式。一下是代碼:
void Start() { Calculate calc = new Calculate();//策略類計算 PersonCalc personC = new PersonCalc(20000); calc.Calc(personC);//同窗內心實際工資 CompCalc comC = new CompCalc工資(20000); calc.Calc(comC);//公司給的實際 } public class calcBase//計算工資的基類 { public virtual void CalcLast() { //計算薪水 } } public class PersonCalc : calcBase//同窗計算工資類 { float LastXinShui;//同窗想要的最終工資 public float XinShui;//所要的薪水 public PersonCalc(float xinShui) { this.XinShui = xinShui; } public override void CalcLast() { LastXinShui = XinShui; Debug.Log("薪水 :" + LastXinShui); } } public class CompCalc : calcBase//公司計算工資類 { float LastXinShui;//公司給的最終工資 float GJJ = 783f;//公積金 float SH = 1652f;//稅 float BX = 356f;//保險 public float XinShui; public CompCalc(float xinShui) { this.XinShui = xinShui; } public override void CalcLast() { LastXinShui = XinShui - GJJ - SH - BX; Debug.Log("薪水 :" + LastXinShui); } } public class Calculate//根據公司或同窗計算最終工資類 { public override void Calc(calcBase calc) { calc.CalcLast(); } }
舉例 2:
有一個高鐵項目,要修建一條從北京到上海,世界上最快的的高鐵。但首先要進行預算,預算最大的一塊即由高鐵距離決定的。因而須要你們計算一個從北京到上海的最近距離。因各自有計算方法,所以這裏用到了策略模式。
public class ContextBase//基礎計算類 { public virtual void Calculate(StrategyBase strategyBase)//根據策略類調用各自的距離 { strategyBase.MoveTo(); } } public abstract class StrategyBase//策略抽象基類 { public abstract void MoveTo();//策略移動抽象方法 } public class StrategyA:StrategyBase//A類繼承於策略基類 { string Name;//名字 float Distance;//距離 public StrategyA(string _name,float _distance)//根據名字,距離構造函數 { this.Name = _name; this.Distance = _distance; } public override void MoveTo()//A計算的距離 { Console.Write("{0}計算北京到上海最近距離是{1}",this.Name,this.Distance); } } public class StrategyB : StrategyBase//B類繼承於策略基類 { string Name;//名字 float Distance;//距離 public StrategyB(string _name, float _distance)//根據名字,距離構造函數 { this.Name = _name; this.Distance = _distance; } public override void MoveTo()//B計算的距離 { Console.Write("{0}計算北京到上海最近距離是{1}", this.Name, this.Distance); } } public class StrategyC : StrategyBase//C類繼承於策略基類 { string Name;//名字 float Distance;//距離 public StrategyC(string _name, float _distance)//根據名字,距離構造函數 { this.Name = _name; this.Distance = _distance; } public override void MoveTo()//C計算的距離 { Console.Write("{0}計算北京到上海最近距離是{1}", this.Name, this.Distance); } } public class StrategyD : StrategyBase { string Name;//名字 float Distance;//距離 public StrategyD(string _name, float _distance)//根據名字,距離構造函數 { this.Name = _name; this.Distance = _distance; } public override void MoveTo()//D計算的距離 { Console.Write("{0}計算北京到上海最近距離是{1}", this.Name, this.Distance); } } =======================================策略模式測試=============================================== static void Main(string[] args) { ConTextBase contex = new ConTextBase(); StrategyBase strategyA = new StrategyA("小明", 1262.35f); StrategyBase strategyB = new StrategyB("小全", 1562.78f); StrategyBase strategyC = new StrategyC("小迪", 1152.65f); StrategyBase strategyD = new StrategyD("小雨", 1625.12f); contex.Calculate(strategyA as StrategyA); Console.WriteLine(); contex.Calculate(strategyB as StrategyB); Console.WriteLine(); contex.Calculate(strategyC as StrategyC); Console.WriteLine(); contex.Calculate(strategyD as StrategyD); Console.WriteLine(); Console.ReadKey(); }