zoukankan      html  css  js  c++  java
  • 大话设计模式读书笔记系列-2.策略模式

    >>>大话设计模式读书笔记系列目录>>>

    策略模式

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

    场景:

    商场售卖商品的时候针对不同场景指定不同的折扣策略(原价消费/折扣消费/返利消费),通过构建不同的对象来实现不同策略切换.

    收费抽象类
    /**
     * 现金收费抽象类
     */
    public abstract class CashSuper {
        /**
         * 现金收取超类的抽象方法,收取现金
         * @param money 原价
         * @return 当前价
         */
        public abstract double acceptCash(double money);
    }
    收费子类
    /**
     * 正常收费子类
     */
    public class CashNormal extends CashSuper {
        @Override
        public double acceptCash(double money) {
            return money;//正常原价返回
        }
    }
    
    /**
     * 打折收费子类
     */
    public class CashRebate extends CashSuper {
    
        /**
         * 费率
         */
        private double moneyRebate = 1d;
    
        /**
         * 打折收费,初始化时,必须输入折扣率,如八折,就是0.8
         *
         * @param moneyRebate
         */
        public CashRebate(String moneyRebate) {
            this.moneyRebate = Double.valueOf(moneyRebate);
        }
    
        @Override
        public double acceptCash(double money) {
            return money * this.moneyRebate;
        }
    }
    
    /**
     * 返利收费子类
     */
    public class CashReturn extends CashSuper {
    
        /**
         * 返利条件,即满足X元
         */
        private double moneyCondition = 0.0d;
        /**
         * 返利金额,即满足条件以后返还X元
         */
        private double moneyReturn = 0.0d;
    
        /**
         * 返利收费,初始化时必须输入返利条件和返利金额,比如满300元减100元,则moneyCondition=300,moneyReturn=100
         *
         * @param moneyCondition 返利条件
         * @param moneyReturn    返利金额
         */
        public CashReturn(String moneyCondition, String moneyReturn) {
            this.moneyCondition = Double.valueOf(moneyCondition);
            this.moneyReturn = Double.valueOf(moneyReturn);
        }
    
        @Override
        public double acceptCash(double money) {
            double result = money;
            //若消费金额大于返利条件就进行返利计算
            if (money > this.moneyCondition) {
                //结果=总消费金额-(总金额整除返利条件)*返还金额,例如消费910元,610=910-(910/300)*100
                result = money - (int) Math.floor(money/this.moneyCondition) * this.moneyReturn;
            }
            return result;
        }
    }
    策略上下文类
    /**
     * 策略上下文类
     */
    public class CashContext {
    
        /**
         * 策略
         */
        private CashSuper cs;
    
        /**
         * 初始化要使用的策略
         *
         * @param cSuper
         */
        public CashContext(CashSuper cSuper) {
            this.cs = cSuper;
        }
    
        /**
         * 获得计算结果
         *
         * @param money
         */
        public double GetResult(String money) {
            return this.cs.acceptCash(Double.valueOf(money));
        }
    }

    调用端

    public class StrategyPatternDemo {
        public static void main(String[] args) {
            //返回结果
            double total = 0.0d;
            //采用正常收费策略
            total = new CashContext(new CashNormal()).GetResult("910");
            System.out.println("采用正常收费策略:" + total);
            //采用打折收费策略
            total = new CashContext(new CashRebate("0.8")).GetResult("910");
            System.out.println("采用打折收费策略:" + total);
            //采用返利收费策略
            total = new CashContext(new CashReturn("300", "100")).GetResult("910");
            System.out.println("采用返利收费策略:" + total);
        }
    }

    结果

    采用正常收费策略:910.0
    采用打折收费策略:728.0
    采用返利收费策略:610.0

    解析:

    1.策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,他可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合.

    2.策略模式的<CashSuper>类层次为<CashContext>定义了一系列的可重用的算法或行为.继承有助于析取出这些算法中的公共功能.

    3.策略模式的优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试.

    4.当不同的行为堆砌再一个类中时,很难避免使用条件语句来进行选择合适的行为,将这些行为封装在一个个独立的<CashSuper>中,可以在使用这些行为的类中消除条件语句.

    5.策略模式就是用来封装算法的,但在实践中,我们发现可以用他来封装几乎任何类型的规则,只要在分析过程中听到需要再不同时间应用不同的业务规则,就可以考虑使用策略模式出来这种变化的可能性.

    6.基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转发给策略模式的<CashContext>对象.

  • 相关阅读:
    LeetCode分类专题(五)——动态规划1-子序列
    LeetCode分类专题(四)——双指针和滑动窗口1
    LeetCode分类专题(三)——二分查找1
    消息队列(一)——Kafka概述
    Java多线程(五)——synchronized关键字原理
    Java多线程(四)——volatile关键字原理
    Redis(五)——主从复制、哨兵
    Redis(四)——过期、持久化、事件
    Redis(三)——底层数据结构
    MySQL知识点
  • 原文地址:https://www.cnblogs.com/ff111/p/11256462.html
Copyright © 2011-2022 走看看