美文网首页
java 设计模式 - 策略模式

java 设计模式 - 策略模式

作者: 钢镚koala | 来源:发表于2018-07-10 19:42 被阅读0次

    一、概念

    策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

    二、使用示例

    现在有一个需求,做一个商场打折计算器,根据客户所购买的单价和数量,进行结算。
    我们把打折活动看成是商场的活动策略

    public abstract class Strategy {
        public abstract void algorithm();
    }
    

    打八折看成策略A

    //具体算法A
    public class ChildStrategyA extends Strategy {
    
        @Override
        public void algorithm() {
            //算法A实现方法
            System.out.print("算法A计算");
            Log.i("test","算法A计算");
        }
    
    }
    

    满300减100看成策略B

    //具体算法B
    public class ChildStrategyB extends Strategy {
    
        @Override
        public void algorithm() {
            //算法A实现方法
            System.out.print("算法B计算");
            Log.i("test","算法B计算");
        }
        
    }
    

    正常收费

    //具体算法C
    public class ChildStrategyC extends Strategy {
    
        @Override
        public void algorithm() {
            //算法A实现方法
            Log.i("test","算法C计算");
        }
        
    }
    

    收费计算类

    public class Cashier {
        Strategy strategy;
    
        public Cashier(Strategy strategy) {
            this.strategy = strategy;
        }
    
        public void account(){
            strategy.algorithm();
        }
    
    }
    

    三种活动收费,调用代码

     val cashier1 = Cashier(ChildStrategyA())
     val cashier2 = Cashier(ChildStrategyB())
     val cashier3 = Cashier(ChildStrategyC())
     cashier1.account()
     cashier2.account()
     cashier3.account()
    

    由于实例化不同的策略,所以最终在调用account()方法时,所获得的结果就不尽相同。结果:

    算法A计算
    算法B计算
    算法C计算
    

    虽然达到了我们想要的结果,但是还不是真正意义上的策略。其实,以真实商场活动环境,正常收费是一种策略,打折收费是一种策略,返利收费又是一种策略,也就是策略模式中说的具体算法。
    现在我们根据上面三种策略,改写一下上面的代码:

    //此处用了策略模式和简单工厂模式结合,如果只用简单工厂模式,我们就会有一个CashFactory.createCashType(String type)返回一个CashSuper。由于只使用简单工厂模式,需要知道两个类CashFactory和CashSuper所以,我们这里为了更好的封装细节,采用策略模式和简单工厂模式结合,对外只暴露CashContext一个类就可以了。
    public class CashContext {
        CashSuper cashSuper = null;
    
        public CashContext(String type) {
            switch (type) {
                case "正常收费":
                    CashNormal cashNormal = new CashNormal();
                    cashSuper = cashNormal;
                    break;
                case "满300 返 100":
                    CashReturn cashReturn = new CashReturn("300", "100");
                    cashSuper = cashReturn;
                    break;
                case "8折":
                    CashRebate cashRebate = new CashRebate("0.8");
                    cashSuper = cashRebate;
                    break;
            }
        }
    
        public double getResult(double money) {
            return cashSuper.acceptCash(money);
        }
    }
    
    //正常现金收费类
    public class CashNormal extends CashSuper {
    
    
        @Override
        public double acceptCash(double money) {
            return money;
        }
    }
    
    //打折收费类
    public class CashRebate extends CashSuper {
    
        private double moneyRebate = 1d;
    
        public CashRebate(String moneyRebate) {
            this.moneyRebate = Double.parseDouble(moneyRebate);
        }
    
        @Override
        public double acceptCash(double money) {
            return money * moneyRebate;
        }
    }
    
    //打折收费类
    public class CashRebate extends CashSuper {
    
        private double moneyRebate = 1d;
    
        public CashRebate(String moneyRebate) {
            this.moneyRebate = Double.parseDouble(moneyRebate);
        }
    
        @Override
        public double acceptCash(double money) {
            return money * moneyRebate;
        }
    }
    

    调用代码

    Double total = 0d;
    CashContext  cashContext = CashContext("8折");
    //买了四件单价100元的秋裤
    total  += cashContext.getResult((100 * 4).toDouble());
    

    测试结果:

    total cost :  320.0
    

    三、策略模式的解析

    通过以上示例,我们发现,策略模式是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有算法,减少了各种算法类与使用算法类之间的耦合。最多的好处是,简单化了单元测试,每个算法都有自己的类,可以通过自己的接口单独测试,也减少了大量的条件语句判断。所以,以后我们在实践中,只要在分析过程中听到需要在不同实践应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

    相关文章

      网友评论

          本文标题:java 设计模式 - 策略模式

          本文链接:https://www.haomeiwen.com/subject/xjjqpftx.html