zoukankan      html  css  js  c++  java
  • 【设计模式】策略模式

    策略模式

      定义:策略模式是定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

      大白话:将原来所有if-else里的具体算法封装各自的类中。

    优点

      1.可以消除大量的if-else语句,想要彻底去掉if-else可以使用策略+工厂模式来实现

      2.提高了算法的保密性和安全性,可以使用这种模式避免暴漏复杂的算法。

      3.具体策略发生修改,对客户端没有影响

    缺点

      1.客户端使用的时候,必须要知道所有的策略类

      2.策略过多的话,会导致类过多。

    比如现在需求是:

    有四类会员:0-普通会员 1-白银会员 2-黄金会员 3-白金会员

    1. 少于1000不打折

    2. 普通会员 不打折

    3. 白银会员 优惠50元

    4. 黄金会员 8折

    5. 白金会员 优惠50元,再打7折

    传统方法

    public class Test {
        public static void main(String[] args) {
            //普通会员 不打折  10000.0
            System.out.println(getResult(10000L, 0));
            //白银会员 优惠50元  9950.0
            System.out.println(getResult(10000L, 1));
            //黄金会员 8折  8000.0
            System.out.println(getResult(10000L, 2));
            //白金会员 优惠50元,再打7折  6965.0
            System.out.println(getResult(10000L, 3));
        }
    
        private static double getResult(long money, int type) {
    
            if (money < 1000) {
                return money;
            }
            if (type == 0) {//普通会员
                System.out.println("普通会员 不打折");
                money = money;
            } else if (type == 1) {//白银会员
                System.out.println("白银会员 优惠50元");
                money = money - 50;
            } else if (type == 2) {//黄金会员
                System.out.println("黄金会员 8折");
                money = (long) (money * 0.8);
            } else {//白金会员
                System.out.println("白金会员 优惠50元,再打7折");
                money = (long) ((money - 50) * 0.7);
            }
            return money;
        }
    }

    使用策略模式

    思路:

    1. 创建策略接口,里面定义计算money的抽象方法。

    2. 创建四个会员策略实现类,实现上面的策略接口。重写计算money的方法

    3. 创建测试类,根据会员类型的不同,new不同的实现类对象。调用对象的计算money的方法。

    //策略接口
    public interface Strategy {
        //计算费用
        double compute(long money);
    }
    
    //四个实现类
    //普通会员
    public class OrdinaryStrategy implements Strategy {
        @Override
        public double compute(long money) {
            System.out.println("普通会员 不打折");
            return money;
        }
    }
    //白银会员
    public class SilverStrategy implements Strategy {
        @Override
        public double compute(long money) {
            System.out.println("白银会员 优惠50元");
            return money - 50;
        }
    }
    //黄金会员
    public class GoldStrategy implements Strategy {
        @Override
        public double compute(long money) {
            System.out.println("黄金会员 8折");
            return money * 0.8;
        }
    }
    //白金会员
    public class PlatinumStrategy implements Strategy {
        @Override
        public double compute(long money) {
            System.out.println("白金会员 优惠50元,再打7折");
            return (money - 50) * 0.7;
        }
    }
    
    //测试类
    public class Test {
        
        public static void main(String[] args) {
            //普通会员 不打折  10000.0
            System.out.println(getResult(10000L, 0));
            //白银会员 优惠50元  9950.0
            System.out.println(getResult(10000L, 1));
            //黄金会员 8折  8000.0
            System.out.println(getResult(10000L, 2));
            //白金会员 优惠50元,再打7折  6965.0
            System.out.println(getResult(10000L, 3));
        }
    
        private static double getResult(long money, int type) {
    
            if (money < 1000) {
                return money;
            }
            Strategy strategy;
            if (type == 0) {//普通会员
                strategy = new OrdinaryStrategy();
            } else if (type == 1) {//白银会员
                strategy = new SilverStrategy();
            } else if (type == 2) {//黄金会员
                strategy = new GoldStrategy();
            } else {//白金会员
                strategy = new PlatinumStrategy();
            }
            return strategy.compute(money);
        }
    }

    工厂+策略模式

    (彻底处理掉if-else)

    //策略接口
    public interface Strategy {
        //计算费用
        double compute(long money);
        // 返回 type
        int getType();
    }
    //四个实现类
    //普通会员策略
    public class OrdinaryStrategy implements Strategy {
        @Override
        public double compute(long money) {
            System.out.println("普通会员 不打折");
            return money;
        }
        // 添加 type 返回
        @Override
        public int getType() {
            return 0;
        }
    }
    //白银会员
    public class SilverStrategy implements Strategy {
        @Override
        public double compute(long money) {
    
            System.out.println("白银会员 优惠50元");
            return money - 50;
        }
        // type 返回
        @Override
        public int getType() {
            return 1;
        }
    }
    //黄金会员
    public class GoldStrategy implements Strategy{
    
        @Override
        public double compute(long money) {
            System.out.println("黄金会员 8折");
            return money * 0.8;
        }
        // type 返回
        @Override
        public int getType() {
            return 2;
        }
    }
    //白金会员
    public class PlatinumStrategy implements Strategy {
        @Override
        public double compute(long money) {
            System.out.println("白金会员 优惠50元,再打7折");
            return (money - 50) * 0.7;
        }
        // type 返回
        @Override
        public int getType() {
            return 3;
        }
    }
    
    //工厂类
    public class StrategyFactory {
        
        private Map<Integer, Strategy> map;
        
        public StrategyFactory() {
            List<Strategy> strategies = new ArrayList<>();
            
            strategies.add(new OrdinaryStrategy());
            strategies.add(new SilverStrategy());
            strategies.add(new GoldStrategy());
            strategies.add(new PlatinumStrategy());
    
            // 看这里 看这里 看这里!
            map = strategies.stream().collect(Collectors.toMap(Strategy::getType, strategy -> strategy));
    
            /* 等同上面
            map = new HashMap<>();
            for (Strategy strategy : strategies) {
                map.put(strategy.getType(), strategy);
            }*/
        }
    
        public static class Holder {
            public static StrategyFactory instance = new StrategyFactory();
        }
    
        public static StrategyFactory getInstance() {
            return Holder.instance;
        }
    
        public Strategy get(Integer type) {
            return map.get(type);
        }
    }
    
    //测试类
    public class Test {
    
        public static void main(String[] args) {
            //普通会员 不打折  10000.0
            System.out.println(getResult(10000L, 0));
            //白银会员 优惠50元  9950.0
            System.out.println(getResult(10000L, 1));
            //黄金会员 8折  8000.0
            System.out.println(getResult(10000L, 2));
            //白金会员 优惠50元,再打7折  6965.0
            System.out.println(getResult(10000L, 3));
        }
    
        private static double getResult(long money, int type) {
    
            if (money < 1000) {
                return money;
            }
    
            Strategy strategy = StrategyFactory.getInstance().get(type);
    
            if (strategy == null){
                throw new IllegalArgumentException("please input right type");
            }
    
            return strategy.compute(money);
        }
    }

    在Java中的应用

      策略接口-Comparator接口

  • 相关阅读:
    POJ 3126 Prime Path
    POJ 2429 GCD & LCM Inverse
    POJ 2395 Out of Hay
    【Codeforces 105D】 Bag of mice
    【POJ 3071】 Football
    【POJ 2096】 Collecting Bugs
    【CQOI 2009】 余数之和
    【Codeforces 258E】 Devu and Flowers
    【SDOI 2010】 古代猪文
    【BZOJ 2982】 combination
  • 原文地址:https://www.cnblogs.com/flyinghome/p/15200182.html
Copyright © 2011-2022 走看看