学习设计模式1策略模式

策略模式的结构

策略模式可以用于定义一系列算法,这些算法完成了相同的工作,只是实现方式不一样而已,而这个策略模式意义在于,可以使用相同的方式来调用不同的算法,减少各种算法类和使用算法类之间的耦合。

下面的Strategy类,为Context定义一系列的可供重用的算法和行为,在下面就是一个算法方法。

  • 抽象策略算法类

    /**
     * @Program: 设计模式
     * @Description: 抽象算法类
     * @Author Mokairui
     * @Date 2020/11/30 20:30
     */
    public abstract class Strategy {
    
        /**
         * 算法方法
         */
        public abstract void AlgorithmInterface();
    
    }
    
    
  • 具体抽象算法类

    /**
     * @Program: 设计模式
     * @Description: 具体算法A
     * @Author Mokairui
     * @Date 2020/11/30 20:36
     */
    public class ConcreteStrategyA extends Strategy {
        @Override
        public void AlgorithmInterface() {
            System.out.println("算法A");
        }
    }
    
    
    /**
     * @Program: 设计模式
     * @Description: 具体算法B
     * @Author Mokairui
     * @Date 2020/11/30 20:36B
     */
    public class ConcreteStrategyB extends Strategy {
        @Override
        public void AlgorithmInterface() {
            System.out.println("算法B");
        }
    }
    
    
    /**
     * @Program: 设计模式
     * @Description: 具体算法C
     * @Author Mokairui
     * @Date 2020/11/30 20:36B
     */
    public class ConcreteStrategyC extends Strategy {
        @Override
        public void AlgorithmInterface() {
            System.out.println("算法C");
        }
    }
    
    
  • 上下文

    /**
     * @Program: 设计模式
     * @Description: 上下文
     * @Author Mokairui
     * @Date 2020/11/30 20:38
     */
    public class Context {
    
        private Strategy strategy;
    
        public Context(Strategy strategy) {
            this.strategy = strategy;
        }
    
        /**
         * 上下文接口实现,调用策略算法类的方法
         */
        public void ContextInterface() {
            strategy.AlgorithmInterface();
        }
    
    }
    
    
  • 测试

    /**
     * @Program: 设计模式
     * @Description: 测试类
     * @Author Mokairui
     * @Date 2020/11/30 20:42
     */
    public class Demo {
    
        public static void main(String[] args) {
    
            Context context = null;
    
            context = new Context(new ConcreteStrategyA());
            context.ContextInterface();
    
            context = new Context(new ConcreteStrategyB());
            context.ContextInterface();
    
            context = new Context(new ConcreteStrategyC());
            context.ContextInterface();
    
        }
    
    }
    
    

说明:策略模式一般用于处理不同的算法,一个抽象算法方法,说明是干嘛的如商场中计算最后支付价格,这个就可以作为抽象策略算法方法,具体的算法实现就是打折啊,满多少减多少啊,特殊日子啊等等。 而上下文那个类就是加载初始化抽象策略方法,并且提供一个接口方法可以让别人来调用,而具体那个方法则是看你初始化的那个具体策略算法是哪一个。

策略模式实现例子

例子的背景:超市的收银,有很多中优惠方式,同时要应对,接下来可能会更换优惠方式的情况。

  • 抽象的收费方式

    package example;
    
    /**
     * @Program: 设计模式
     * @Description: 抽象的收费方式
     * @Author Mokairui
     * @Date 2020/11/30 21:56
     */
    public abstract class CashSuper {
        /**
         * 抽象的收费方式
         * @return
         */
        public abstract double acceptCash(double money);
    }
    
    
  • 三个具体的收费方式

    package example;
    
    /**
     * @Program: 设计模式
     * @Description: 正常的收费,没有任何优惠
     * @Author Mokairui
     * @Date 2020/11/30 21:57
     */
    public class CashNormal extends CashSuper {
        @Override
        public double acceptCash(double money) {
            return money;
        }
    }
    
    
    package example;
    
    /**
     * @Program: 设计模式
     * @Description: 打折收费子类
     * @Author Mokairui
     * @Date 2020/11/30 22:00
     */
    public class CashRebate extends CashSuper {
        // 打折
        private double moneyRebate = 1d;
    
        public CashRebate() {
        }
    
        // 在类初始的时候如果传参, 则就是打折数,如果没有默认不打折
        public CashRebate(double moneyRebate) {
            this.moneyRebate = moneyRebate;
        }
    
        @Override
        public double acceptCash(double money) {
            return money * moneyRebate;
        }
    }
    
    
    package example;
    
    /**
     * @Program: 设计模式
     * @Description: 返利收费子类
     * @Author Mokairui
     * @Date 2020/11/30 22:05
     */
    public class CashReturn extends CashSuper {
    
        // 满多少的条件
        private double moneyCondition = 0.0d;
        // 满了后返利的费用
        private double moneyReturn = 0.0d;
    
        public CashReturn() {
        }
    
        public CashReturn(double moneyCondition, double moneyReturn) {
            this.moneyCondition = moneyCondition;
            this.moneyReturn = moneyReturn;
        }
    
        @Override
        public double acceptCash(double money) {
            if (money >= moneyCondition) {
                // 减去返利的钱,每满moneyCondition就减一次
                money = money - Math.floor(money / moneyReturn) * moneyReturn;
            }
            return money;
        }
    }
    
    
  • 策略和简单共厂相结合的上下文,初始化策略模式

    package example;
    
    /**
     * @Program: 设计模式
     * @Description: 策略和简单工厂结合,上下文
     * @Author Mokairui
     * @Date 2020/12/1 20:48
     */
    public class CashContext {
    
        private CashSuper cs;
    
        public CashContext(String type) {
            switch (type) {
                case "正常收费":
                    CashNormal cs0 = new CashNormal();
                    cs = cs0;
                    break;
                case "打8折":
                    CashRebate cs1 = new CashRebate(0.8);
                    cs = cs1;
                    break;
                case "满300减100":
                    CashReturn cs2 = new CashReturn(300, 100);
                    cs = cs2;
                    break;
                default:
                    break;
            }
        }
    
        public double GetResult(double money) {
            return cs.acceptCash(money);
        }
    
    }
    
    
  • 客服端,测试

    package example;
    
    /**
     * @Program: 设计模式
     * @Description: 客服端
     * @Author Mokairui
     * @Date 2020/12/1 20:59
     */
    public class Demo {
    
    
        public static void main(String[] args) {
            double total = 350.0d;
            CashContext csuper = new CashContext("满300减100");
            double totalPrice = 0d;
            totalPrice = csuper.GetResult(total);
            System.out.println(totalPrice);
        }
    
    }
    
    

应用场景:它可以封装几乎所有的规则,就是在需要在不同时间应用不同的业务规则(在例子中就是打折,正常收费,满减的这三种规则),就可以考虑使用策略模式来封装这些规则。

posted on 2020-12-01 21:57  莫铠瑞  阅读(31)  评论(0)    收藏  举报