码迷,mamicode.com
首页 > 其他好文 > 详细

不一样的策略模式(设计模式五)

时间:2019-12-29 10:43:36      阅读:94      评论:0      收藏:0      [点我收藏+]

标签:break   根据   时间轴   存在   概念   rpo   vat   cep   二进制   

前言

什么是设计模式?说白了就是套路,是经过历代程序员总结出来的。很多时候我们虽然学会了很多套路,但是啥时候使用,使用哪个合适,我想这才是问题的关键。
知道怎么用不知道什么时候用,这时候看下代码风格也行用的上,策略模式是非常容易通过代码风格使用上的。
策略模式,为什么叫策略模式呢?其实策略模式还有一个别名叫做政策(policy)模式,在古代,对不同的国家呢,实行不同的政策,对A呢,采取税务10%,对B国采取税务20%。
这样根据不同国家政策不同呢,在计算机中就是根据不同对象采取不同的方法,就叫做策略模式咯。但是呢,如果直接采用if else 这种行为呢,人们发现过于臃肿,且复用性极差,那么就形成了这样一种模式去缓解这个问题。
策略模式属于对象行为模式,其实不去看概念也很好记,在运行时针对不同对象,去做出相应的行为。至于为什么不分到结构型或者其他型,只是它更符合行为型,一个类的行为或其算法可以在运行时更改,这些分类其实没有绝对的界限,只是有权威人士对其进行了规划。
那么策略模式的风格是什么,查看正文。

开车出发

public enum PolicyBase
{
    US_Policy,
    DE_Policy,
    FR_Policy
}
public class Strategy
{
    PolicyBase policyBase;

    public Strategy(PolicyBase policyBase) {
        this.policyBase = policyBase;
    }
    public double CalculatePolicy() {
        if (policyBase == PolicyBase.US_Policy)
        {
            return 0.9;
        }
        else if (policyBase == PolicyBase.DE_Policy)
        {
            return 0.8;
        }
        else if (policyBase == PolicyBase.FR_Policy)
        {
            return 0.1;
        }
        return 0;
    }
}

根据不同的国家,采取了不同的政策。这样一看好像没有啥问题啊,根据了不同国家制定了不同税法。
但是呢,在开发代码的时间轴上,也就是未来的角度上存在的极大的问题。比如和英国(GB)合作了,我得改吧?然后又和另外一个国家合作了,恐怕又得来一遍。
这时候有人就纳闷了,还想不改代码?代码的确是要改的,但是不能违法了封闭开发原则。
技术图片
技术图片
在红色部分呢,是我们需要继续往下添加代码的地方,也就是我们加一个国家就需要把我们写过的任何一个区域改一遍。
我想这就很糟糕了,牵扯太大,对于发布来说就需要测试整个子模块,我想这代价无法让人接受,这时候策略者模式就出现了。

public enum PolicyBase
{
    US_Policy,
    DE_Policy,
    FR_Policy
}
public interface Policy
{
    double Calculate();
}

public class USPolicy : Policy
{
    public double Calculate()
    {
        throw new NotImplementedException();
    }
}

public class DEPolicy : Policy
{
    public double Calculate()
    {
        throw new NotImplementedException();
    }
}

public class FRPolicy : Policy
{
    public double Calculate()
    {
        throw new NotImplementedException();
    }
}

public class StrategyFactory{
    Policy policy;
    public StrategyFactory(PolicyBase policyBase) {
        switch (policyBase)
        {
            case PolicyBase.US_Policy:
                policy = new USPolicy();
                break;
            case PolicyBase.DE_Policy:
                policy = new DEPolicy();
                break;
            case PolicyBase.FR_Policy:
                policy = new FRPolicy();
                break;
        }
    }
    public Policy GetPolicy() {
        return policy;
    }
}

class SalesOrder
{
    private Policy Policy;

    public SalesOrder(StrategyFactory strategyFactory)
    {
        this.Policy = strategyFactory.GetPolicy();
    }

    public double CalculatePolicy()
    {
        double val = Policy.Calculate();
        return val;
    }

};

上述代码中,通过策略者模式把原来的获取各国的税法比例变成了SalesOrder类,而这个类不再改变,也就是说所以依赖于获取各国税法参数的将依赖于一个稳定的类。
这时候很多纳闷了,如果我需要添加一个英国(GB),依然需要在红色部分就行修改啊,修改的地方如下:
技术图片
技术图片
修改的地方一样多,且还要多加一个GBPolicy类,这不是白忙活了吗?
首先我们来看下前后依赖关系图:
使用策略模式前:
技术图片
使用策略模式后:
技术图片
这样一看,不仅是没有啥好处,还复杂了。
然而这样一想,我们处理的是解决这个税法问题这个业务上,可以肯定的就是使用策略模式后,我下面红框部分稳定了,也就是在二进制上可以复用,但是上面红色部分倒是有问题了,耦合太大。
但是呢,我们知道上面复杂部分其实就是简单工厂模式,问题就回到了如何优化简单工厂模式了,如果能解决上面红框的问题,那么是可行的。
由于篇幅有限,下一篇总结工厂模式到抽象工厂到反射这个演化。
这时候我们看到了,如果遇到了if else 且以后会增加else if,可以用策略模式,去缓解这个问题,增加代码复用性。
但是稳定的if else 呢是不需要的,比如说星期一到星期日,这种就是稳定的了,本来处于稳定的,那么其改变的价值就不是很大。

uml图

后续补上

总结

策略模式的作用,解决使用不稳定 的if...else 所带来的复杂和难以维护。

不一样的策略模式(设计模式五)

标签:break   根据   时间轴   存在   概念   rpo   vat   cep   二进制   

原文地址:https://www.cnblogs.com/aoximin/p/12090000.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!