策略模式(六)

原创
2017/08/12 17:34
阅读数 15

策略模式

定义:

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

 

优点

1、   提供了一种替代继承的方法,而且既保持了继承的优点(代码重用),还比继承更灵活(算法独立,可以任意扩展);

2、   避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展;

3、   遵守大部分GRASP原则和常用设计原则,高内聚、低偶合;

4、   易于进行单元测试,各个算法区分开,可以针对每个算法进行单元测试;

5、   ……

缺点

1、   因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量;

2、   选择何种算法需要客户端来创建对象,增加了耦合,这里可以通过与工厂模式结合解决该问题;

3、   程序复杂化。

 

举例 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();
        }

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部