zoukankan      html  css  js  c++  java
  • 如何干掉 if else 策略+工厂

    无论我们做什么业务都无法避免 if else, 但是多重又会导致很多if,今天我们来讲讲如何干掉if else 让你摆脱被if else 支配的恐惧.

    
    

     首先让我们来看看简单的if else 语句

    public void test(TestUser testUser) {
    if (Objects.isNull(testUser)){
    System.out.println("执行业务 一");
    } else {
    System.out.println("执行业务 二");
    }
    }

      并没有什么问题.但是如果业务稍微复杂一些呢,我们再来看看
      首先贴出用户实体类

    @Data
    public class TestUser {
    private Integer id;
    private String name;
    private Viplevel vipLevel;
    }

      在贴出用户VIP枚举

    @Getter
    @AllArgsConstructor
    public enum Viplevel implements Serializable, IEnum {

    NOVIP(0, "普通用户","普通用户"),
    VIP_LEVEL1(1, "包月会员","包月会员"),
    VIP_LEVEL2(2, "季度会员","季度会员"),
    VIP_LEVEL3(3, "半年会员","半年会员"),
    VIP_LEVEL4(4, "年费会员","年费会员");

    private final Integer code;

    private final String desc;

    private final String msg;

    @JsonCreator
    public static Viplevel jsonCreator(Integer code) {
    for (Viplevel value : Viplevel.values()) {
    if (value.getCode().equals(code)) {
    return value;
    }
    }
    return null;
    }

    @JsonValue
    public Map getResult() {
    Map<String, Object> map = new LinkedHashMap<String, Object>();
    map.put("code", getCode());
    map.put("desc", getDesc());
    map.put("msg", getMsg());
    return map;
    }
    @Override
    public Serializable getValue() {
    return this.code;
    }
    }

      再来看看业务

    public double sellMoney(TestUser testUser) {
    double proPrice = 3000;
    double resultMoney = proPrice;
    if (Objects.isNull(testUser)) {
    //抛出异常
    return proPrice;
    } else {
    if (Viplevel.NOVIP.equals(testUser.getVipLevel())) {
    System.out.println("普通用户");
    resultMoney = proPrice;
    } else if (Viplevel.VIP_LEVEL1.equals(testUser.getVipLevel())) {
    System.out.println("包月会员");
    resultMoney = proPrice - 100;
    } else if (Viplevel.VIP_LEVEL2.equals(testUser.getVipLevel())) {
    System.out.println("季度会员");
    resultMoney = proPrice - 300;
    } else if (Viplevel.VIP_LEVEL3.equals(testUser.getVipLevel())) {
    System.out.println("半年会员:");
    resultMoney = proPrice * 0.8;
    } else if (Viplevel.VIP_LEVEL4.equals(testUser.getVipLevel())) {
    System.out.println("年会员:");
    resultMoney = proPrice * 0.3;
    }
    return resultMoney;
    }
    }

      天哪,这只是一个简单的例子,竟然出现如此多让人懊恼的语句.那么该如何解决呢,别着急,让我们一步步来干掉讨厌的 if else
      首先思考,最终结果就是要获取到最终产品的售价,那我们就写个计算结果的方法,再让接口去继承他,这样不就能根据需求计算得到结果了吗

    /**
    * @author NYY
    * @decription 普通用户最终产品售价
    */
    public class NormalStrategy implements ComputeStrategy {
    @Override
    public double compute(double money) {
    return money;
    }
    }
    /**
    * @author NYY
    * @date 2020/6/4$
    * @decription 月会员最后售价
    */
    public class MonthStrategy implements ComputeStrategy {
    @Override
    public double compute(double money) {
    return money - 100;
    }
    }

      ....以此类推
      那么我们最终的业务实现是这样的

    private static double getResultMoney(TestUser testUser) {
    double proPrice = 3000;
    double resultMoney = proPrice;
    if (Objects.isNull(testUser)) {
    //抛出异常
    return proPrice;
    } else {
    if (Viplevel.NOVIP.equals(testUser.getVipLevel())) {
    resultMoney = new NormalStrategy().compute(proPrice);
    } else if (Viplevel.VIP_LEVEL1.equals(testUser.getVipLevel())) {
    resultMoney = new MonthStrategy().compute(proPrice);
    }
    //......
    }
    return resultMoney;
    }

      在优化一下变成了这样

    private static double getResultMoneyTwo(TestUser testUser) {
    double proPrice = 3000;
    double resultMoney = proPrice;
    ComputeStrategy computeStrategy = null;
    if (Objects.isNull(testUser)) {
    //抛出异常
    return proPrice;
    } else {
    if (Viplevel.NOVIP.equals(testUser.getVipLevel())) {
    computeStrategy = new NormalStrategy();
    } else if (Viplevel.VIP_LEVEL1.equals(testUser.getVipLevel())) {
    computeStrategy = new MonthStrategy();
    }
    //......
    //最后计算结果
    return computeStrategy.compute(proPrice);
    }
    }

      什么,if else 居然还在,我们发现,它需要的不仅是计算结果,主要是根据用户类型,好吧,那我们吧用户类型也提出来

    public interface ComputeStrategyTwo {
    // 计算方法
    double compute(double money);
    //获取用户类型
    Integer getUserType();
    }

      接口继承时实现这两个方法

      新增的 getUserType 方法,主要用来标示该策略的type 值。

    /**
    * @author NYY
    * @decription 普通用户
    */
    public class NewNormalStrategy implements ComputeStrategyTwo{
    @Override
    public double compute(double money) {
    return money;
    }
    @Override
    public Integer getUserType() {
    return Viplevel.NOVIP.getCode();
    }
    }
    /**
    * @author NYY
    * @decription 月会员最后售价
    */
    public class NewMonthStrategy implements ComputeStrategyTwo {
    @Override
    public double compute(double money) {
    return money - 100;
    }
    @Override
    public Integer getUserType() {
    return Viplevel.VIP_LEVEL1.getCode();
    }
    }


      重点又来了,这时我们就再把策略的工厂加进来

    /**
    * @author NYY
    * @decription
    */
    public class ComputeStrategyFactory {
    private Map<Integer, ComputeStrategyTwo> map;
    public ComputeStrategyFactory() {

    List<ComputeStrategyTwo> strategies = new ArrayList<>();
    strategies.add(new NewNormalStrategy());//普通用户
    strategies.add(new NewMonthStrategy());//包月用户
    //.......

    // java 8 stream流
    map = strategies.stream().collect(Collectors.toMap(ComputeStrategyTwo::getUserType, computeStrategy -> computeStrategy));
    }

    public static class Possessor {
    public static ComputeStrategyFactory instance = new ComputeStrategyFactory();
    }

    public static ComputeStrategyFactory getInstance() {
    return Possessor.instance;
    }

    public ComputeStrategyTwo get(Integer type) {
    ComputeStrategyTwo computeStrategyTwo = map.get(type);
    return computeStrategyTwo;
    }
    }

      这样我们策略的工厂也有了.最终让我们看看处理业务的代码变成什么样了呢.

    private static  double lastResultMoney(TestUser testUser){
    double proPrice = 3000;
    Objects.requireNonNull(testUser,"用户对象为空了");

    ComputeStrategyTwo computeStrategyTwo = ComputeStrategyFactory.getInstance().get(testUser.getVipLevel().getCode());
    if(Objects.isNull(computeStrategyTwo)){
    // throw new GlobalException("用户类型未知");
    // 抛出全局异常
    }
    return computeStrategyTwo.compute(proPrice);
    }

      怎么样 最终我们通过策略+工厂的方式实现了业务,再也没看见令人讨厌的if else 语句.

      至此完结 !!! 文章未经博主同意禁止转载,转载请赋连接

  • 相关阅读:
    迁移-Mongodb时间类数据比较的坑
    Kong在windows10的hyperV CentOS上安装
    C#文件上传编码乱码
    入职9个月感想
    单元测试遇到的Mock重载方法问题
    MongoDB wiredTiger存储引擎下的存储方式LSM和B-Tree比较
    【SQL Server】修改DB逻辑文件名称
    【winform】基于UserControl实现webBrower组件时html页面元素加载及onclick事件监听实现
    SQL server 数据连接池使用情况检测
    【Vue起步-Windows】N01:环境安装
  • 原文地址:https://www.cnblogs.com/Java-zhitu/p/13090537.html
Copyright © 2011-2022 走看看