代码检视问题总结
首先来看一段代码
// 依据 Y01, Y03 匹配 公募基金一年、三年的数据
for (ProfitRelative profitRelative : publicFund.getProfitRelativeList()) {if ("Y01".equals(profitRelative.getDuration())) {profits[0] = profitRelative.getProfitRate();
if (profitRelative.getProfitRank() == null || profitRelative.getProfitRank() == 0 || profitRelative.getProfitRankTotal() == null || profitRelative.getProfitRankTotal() == 0){exceedRank[0] = null;
}else {exceedRank[0] = 100 - (profitRelative.getProfitRank() * 100 / profitRelative.getProfitRankTotal());
}
} else if ("Y03".equals(profitRelative.getDuration())) {profits[1] = profitRelative.getProfitRate();
if (profitRelative.getProfitRank() == null || profitRelative.getProfitRank() == 0 || profitRelative.getProfitRankTotal() == null || profitRelative.getProfitRankTotal() == 0){exceedRank[1] = null;
}else {exceedRank[1] = 100 - (profitRelative.getProfitRank() * 100 / profitRelative.getProfitRankTotal());
}
}
}
乍一看令人恐怖。上面咱们一步一步地,对它进行重构。
反复是万恶之源
反复 1:分支 Y01 与 分支 Y03,逻辑完全一致。此时咱们执行第一个重构伎俩,将这段一样的逻辑抽成一个办法。
private static double winPercent() {if (profitRelative.getProfitRank() == null || profitRelative.getProfitRank() == 0 || profitRelative.getProfitRankTotal() == null || profitRelative.getProfitRankTotal() == 0){return = null;}else {return 100 - (profitRelative.getProfitRank() * 100 / profitRelative.getProfitRankTotal());
}
}
反复 2:判断 int 是否为非空非 0。此时咱们执行同样的重构伎俩
private static boolean anyNullOrZero(Integer ...values) {for (Integer value : values){if (value == null || value == 0){return true;}
}
return false;
}
private static double winPercent(ProfitRelative profitRelative) {if ( anyNullOrZero(profitRelative.getProfitRank(), profitRelative.getProfitRankTotal()) ){return = null;} else {return 100 - (profitRelative.getProfitRank() * 100 / profitRelative.getProfitRankTotal());
}
}
翻转判断,缩小分支
if
语句外面尽可能不要用 !
,而且尽可能突出外围逻辑。上面执行第二个重构伎俩。首先将
public class XXUtils {
// 如果须要取反,间接加一个办法,比在判断语句中应用 `!` 要好很多
public static boolean noneNullOrZero(Integer ...values){return ! anyNullOrZero(values);
}
private static boolean anyNullOrZero(Integer ...values) {for (Integer value : values){if (value == null || value == 0){return true;}
}
return false;
}
}
private static double winPercent(ProfitRelative profitRelative) {
// 翻转,去除一个没用的 else 分支
if (XXUtils.noneNullOrZero(profitRelative.getProfitRank(), profitRelative.getProfitRankTotal()) ){return 100 - (profitRelative.getProfitRank() * 100 / profitRelative.getProfitRankTotal());
}
return null;
}
办法下沉,畛域充血
getWinPercent()
应该下沉到类 ProfitRelative
外面,作为一个成员办法。
这里须要重点强调一下,很多同学喜爱把逻辑都往 service 外面堆放,导致代码贫血甚至失血。其实只有将逻辑放到畛域对象外面,就能够使逻辑清晰很多,让代码充血。
public class ProfitRelative {
private Integer profitRank;
private Integer profitRankTotal;
public Integer getWinPercent(){if ( noneNullOrZero(profitRank, profitRankTotal)) {return 100 - (profitRank * 100 / profitRankTotal);
}
return null;
}
}
最初,开始那坨代码变成这样:
// 依据 Y01, Y03 匹配 公募基金一年、三年的数据
for (ProfitRelative profitRelative : publicFund.getProfitRelativeList()) {if ("Y01".equals(profitRelative.getDuration())) {profits[0] = profitRelative.getProfitRate();
exceedRank[0] = profitRelative.getWinPercent();} else if ("Y03".equals(profitRelative.getDuration())) {profits[1] = profitRelative.getProfitRate();
exceedRank[1] = profitRelative.getWinPercent();}
}
下面这坨代码 依然有改良空间,能够继续执行重构手法。这里只是展现重构是如何一步一步施行的:小幅批改,测试,再批改。