定义:面试
策略模式定义了一系列的算法,并将每个算法封装起来,并且使它们还能够相互替换。策略模式让算法独立于使用它的客户而独立变化。算法
一、 提供了一种替代继承的方法,并且既保持了继承的优势(代码重用),还比继承更灵活(算法独立,能够任意扩展);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(); }