【设计模式】策略模式

策略模式

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

  大白话:将原来所有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接口

 

posted @ 2021-08-28 15:31  夏夜凉凉  阅读(73)  评论(0编辑  收藏  举报