消除代码里的if-else

89 阅读2分钟

方式一:枚举类优化if-else

package org.example.auth.test;
...
public class MyTest {
    @Test
    void contextLoads() {
        String payType = "weixin";
        //if-else
        if ("weixin".equals(payType)) {
            Pay.weixin.toPrintln();
            Pay.weixin.toPay();
        } else {
            Pay.zhifubao.toPrintln();
            Pay.zhifubao.toPay();
        }

        //根据payType执行相应逻辑,避免if-else
        Pay.valueOf(payType).toPrintln();
        Pay.valueOf(payType).toPay();
    }
}

enum Pay {
    //枚举类构造方法创建枚举项
    weixin(104, "微信") {
        //枚举项实现抽象方法执行自己的特殊逻辑
        @Override
        public void toPay() {
            //调用枚举项的属性和方法
            Integer code = weixin.getCode();
            System.out.println(weixin.msg + "=====>" + code);
        }
    },
    zhifubao(108, "支付宝") {
        @Override
        public void toPay() {
            System.out.println(zhifubao.msg + "=====>" + zhifubao.code);
        }
    };
    
    private Integer code;
    private String msg;
    //构造方法
    Pay(Integer code, String msg) {this.code = code;this.msg = msg;}
    public Integer getCode() {return this.code;}
    
    //通用方法在类里实现
    public void toPrintln() {
        System.out.println(this.msg);
    }
    //特殊性方法定义抽象,让枚举项自己实现
    public abstract void toPay();
}

枚举类普通类一样有属性、构造方法、getter、setter、抽象方法、继承、实现接口等等,区别在于枚举类的实例是固定可枚举的,枚举实例天然就是单例的

方式二:Map+函数式接口

需求

最近写了一个服务:根据优惠券的类型resourceType和编码resourceId来 查询 发放方式grantType和领取规则

switch(resourceType){  
 case "红包":   
  查询红包的派发方式   
  break;  
 case "购物券":   
  查询购物券的派发方式  
  break;  
 case "QQ会员" :  
  break;  
 case "外卖会员" :  
  break;  
 ......  
 default : logger.info("查找不到该优惠券类型resourceType以及对应的派发方式");  
  break;  
}

如果要这么写的话, 一个方法的代码可就太长了,影响了可读性。(别看着上面case里面只有一句话,但实际情况是有很多行的) 而且由于 整个 if-else的代码有很多行,也不方便修改,可维护性低。

实现方式

用上了Java8的新特性lambda表达式

  • 判断条件放在key中
  • 对应的业务逻辑放在value中

根据优惠券类型resourceType -> 确定查询哪个数据表 根据编码resourceId -> 到对应的数据表里边查询优惠券的派发方式grantType和领取规则

@Service  
public class QueryGrantTypeService {  
   
    @Autowired  
    private GrantTypeSerive grantTypeSerive;  
    private Map<String, Function<String,String>> grantTypeMap=new HashMap<>();  
  
    /**  
     *  初始化业务分派逻辑,代替了if-else部分  
     *  key: 优惠券类型  
     *  value: lambda表达式,最终会获得该优惠券的发放方式  
     */  
    @PostConstruct  
    public void dispatcherInit(){  
        grantTypeMap.put("红包",resourceId->grantTypeSerive.redPaper(resourceId));  
        grantTypeMap.put("购物券",resourceId->grantTypeSerive.shopping(resourceId));  
        grantTypeMap.put("qq会员",resourceId->grantTypeSerive.QQVip(resourceId));  
    }  
   
    public String getResult(String resourceType){  
        //Controller根据 优惠券类型resourceType、编码resourceId 去查询 发放方式grantType  
        Function<String,String> result=getGrantTypeMap.get(resourceType);  
        if(result!=null){  
            //传入resourceId 执行这段表达式获得String型的grantType  
            return result.apply(resourceId);  
        }  
        return "查询不到该优惠券的发放方式";  
    }  
}

GrantTypeSerive

@Service  
public class GrantTypeSerive {  
  
    public String redPaper(String resourceId){  
        //红包的发放方式  
        return "每周末9点发放";  
    }  
    public String shopping(String resourceId){  
        //购物券的发放方式  
        return "每周三9点发放";  
    }  
    public String QQVip(String resourceId){  
        //qq会员的发放方式  
        return "每周一0点开始秒杀";  
    }  
}