代码检视问题总结
首先来看一段代码
//依据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(); } }
下面这坨代码依然有改良空间,能够继续执行重构手法。这里只是展现重构是如何一步一步施行的:小幅批改,测试,再批改。