JAVA系列---优化 if/else

1. 背景

while (itpa.hasNext()) {
    JmlPcPosteractivity pa = itpa.next();
    BigDecimal award = pa.getAwardNum();
    String prizeCode = String.valueOf(pa.getPrizeId());
    sum = sum.add(award);
    if(detailNum.containsKey(prizeCode)){
        detailNum.put(prizeCode,new BigDecimal(detailNum.get(prizeCode).toString()).add(award));
    }else {
        detailNum.put(prizeCode,award);
    }
    ActivityVO avo = new ActivityVO();
    JmlPrize p = skus.getObject(prizeCode,JmlPrize.class);
    JmlPcActivityname a = activityInfo.getObject(pa.getActivityId().toString(),JmlPcActivityname.class);
    int convertCount = iJmlMpPosterflowingService.count(new QueryWrapper<JmlMpPosterflowing>().eq("poster_code",pa.getPosterQrcode()).eq("convert_status",1));
    avo.setId(pa.getId());
    avo.setPosterQrcode(pa.getPosterLink());
    avo.setActivityType(pa.getActivityType());
    avo.setPrizeName(p.getPrizeName());
    avo.setActivityName(a.getActivityName());
    avo.setStartTime(pa.getStartTime());
    avo.setEndTime(pa.getEndTime());
    avo.setPrizeUnit(p.getUnit());
    avo.setTotalNum(new BigDecimal(pa.getQrcodeTotalNum()).multiply(pa.getPrizeRule()));
    avo.setUseNum(new BigDecimal(pa.getQrcodeUsedNum()).multiply(pa.getPrizeRule()));
    avo.setConvertNum(new BigDecimal(convertCount).multiply(pa.getPrizeRule()));
    avo.setAwardNum(pa.getAwardNum());
    avo.setAwardRule(pa.getAwardRule());
    if(pa.getQrcodeStatus().equals(JmlEnum.PosterQrcodeStatus.CANCEL.getStatus()) || pa.getQrcodeStatus().equals(JmlEnum.PosterActivityStatus.CANCEL.getStatus())){
        avo.setStatus(JmlEnum.PosterActivityStatus.CANCEL.getStatus());
    }else if(pa.getStartTime().compareTo(now) > 0){
        avo.setStatus(JmlEnum.PosterActivityStatus.NOSTART.getStatus());
    }else if(pa.getEndTime().compareTo(now) < 0){
        avo.setStatus(JmlEnum.PosterActivityStatus.END.getStatus());
    }else {
        avo.setStatus(JmlEnum.PosterActivityStatus.START.getStatus());
    }
    avos.add(avo);
}

判断可以说是我们程序中必不可少的逻辑处理方式,最简单的就是 if / else 语句,以上就是最常见if/else if,用时候确实很爽。

但是,大量使用if / else 会使程序变得臃肿和冗长,而且随着时间推移,业务的增加,也会导致代码逻辑复杂,维护性差,而且改一点就需要回忆整个逻辑。

因此,禁止使用if/else if 语句!!!

2. 优化方案

1. 简化 else

场景:只有 if 和else ,符合/不符合条件的操作无交集。

---- 去掉else分支,if分支使用return提前返回

优点:方便扩展,后续容易加逻辑

优化前:

if (id == null) {
    // TODO 新增记录
} else {
    // TODO 修改记录
}

优化后:

if (id == null) {
    // TODO 新增记录
    return;
}
// TODO 修改记录

2. 三目运算符

场景:符合/不符合条件操作后的返回值不同。

---- 三目运算符赋值

优点:节约代码量,逻辑清晰(但其实不利于维护)

优化前:

String name;
if (user == null) {
    name = "无名氏";
} else {
    name = user.getName();
}

优化后:

String name = user == null ? "无名氏" : user.getName();

3. Java 8 Optional 类

场景:需要对值进行 null 判断。

---- Optional 可以把它想象成一个容器,值存在则 isPresent() 为 true,再调用 get() 会返回该对象。

优点:可以很好地避免烦人的 NPE。

优化前:

String name;
if (user == null) {
    name = "无名氏";
} else {
    name = user.getName();
}

优化后:

// ofNullable()里可以放 null 值;of()里放 null 会抛出空指针异常 NullPointerException
Optional<User> optionalUser = Optional.ofNullable(user);
String name = optionalUser.isPresent() ? optionalUser.get().getName() : "无名氏";

Optional 的另一种使用方式

优化前:

private void printName(String name) {
    if (name == null) {
        name = "无名氏";
    }
    log.info("姓名:{}", name);
}

优化后:

private void printName(String name) {
    // 如果值存在,正常返回里面的值,否则返回默认值(无名氏)
    Optional<String> optional = Optional.ofNullable(name);
    log.info("姓名:{}", optional.orElse("无名氏"));
}

4. 卫语句

场景:多种条件判断,都为 true 才能执行。(如果代码中使用的 if / else 超过了三层,建议替换,避免后续代码维护困难)

---- 卫语句

优点:可读性高;当有条件不需要后可以直接删除相应“开关”,更加直观。

优化前:

if (id == null) {
    log.error("id 为空");
    return;
} else if (name == null) {
    log.error("姓名为空");
    return;
} else if (age < 0) {
    log.error("年龄需要大于0");
    return;
}        
// TODO 正常执行

优化后:

if (id == null) {
    log.error("id 为空");
    return;
}
if (name == null) {
    log.error("姓名为空");
    return;
}
if (age < 0) {
    log.error("年龄需要大于0");
    return;
}
// TODO 正常执行

5. switch语句

场景:不同条件下执行的操作或返回的值不一样

---- 多重else if可以使用switch替换

优点:可读性高;当有条件不需要后可以直接删除相应开关,更加直观。

优化前:

int a = 2;
int b = 5;
if ("PLUS".equals(opt)) {
    return a + b;
} else if ("MINUS".equals(opt)){
    return a - b;
} else if ("MULTIPLY".equals(opt)) {
    return a * b;
} else {
    return a / b;
}

优化后:

private int calculate(String opt) {
    int a = 2;
    int b = 5;
    switch (opt) {
        case "plus":
            return a + b;
        case "minus":
            return a - b;
        case "multiply":
            return a * b;
        default:
            return a / b;
    }
}

6. 策略模式

场景:不同条件下需要执行不同的操作

---- 采用枚举实现策略模式

优点:这样我们的代码就很好地做到了横向扩展,不用再写一堆的 if / else 进行判断,后期维护也变得更容易了。
用到策略模式的场景还有很多,比如订单来源不同需要做不同操作,使用优惠券打折分折扣券和抵扣券……

优化前:

public Integer count(Integer a, Integer b, String opt) {
    if ("PLUS".equals(opt)) {
        return a + b;
    } else if ("MINUS".equals(opt)){
        return a - b;
    } else if ("MULTIPLY".equals(opt)) {
        return a * b;
    } else {
        return a / b;
    }
}

优化后:

public interface ArithmeticOperation {
    
    /**
     * 计算
     *
     * @param a 待计算值
     * @param b 待计算值
     * @return 计算结果
     */
    int calculate(int a, int b);
 
}
public enum ArithmeticEnum implements ArithmeticOperation {
 
    /**
     * 加
     */
    PLUS {
        @Override
        public int calculate(int a, int b) {
            return a + b;
        }
    },
    /**
     * 减
     */
    MINUS {
        @Override
        public int calculate(int a, int b) {
            return a - b;
        }
    },
    /**
     * 乘
     */
    MULTIPLY {
        @Override
        public int calculate(int a, int b) {
            return a * b;
        }
    },
    /**
     * 除
     */
    DIVIDE {
        @Override
        public int calculate(int a, int b) {
            return a / b;
        }
    };
 
}
public Integer count(Integer a, Integer b, String opt) {
    ArithmeticEnum arithmeticEnum = ArithmeticEnum.valueOf(opt);
    return arithmeticEnum.calculate(a, b);
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lipviolet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值