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);
}