为什么要重构?如何重构?这个宝典请一定收藏!( 五 )


移除对参数的赋值
public int discount(int inputVal, int quantity, int yearToDate) {if (inputVal > 50) inputVal -= 2;if (quantity > 100) inputVal -= 1;if (yearToDate > 10000) inputVal -= 4;return inputVal;}public int discount(int inputVal, int quantity, int yearToDate) { int result = inputVal;if (inputVal > 50) result -= 2; if (quantity > 100) result -= 1; if (yearToDate > 10000) result -= 4; return result; }复制代码
将查询与修改分离
任何有返回值的方法 , 都不应该有副作用
移除不必要临时变量
临时变量仅使用一次或者取值逻辑成本很低的情况下
引入解释性变量
将复杂表达式(或其中一部分)的结果放进一个临时变量 , 以此变量名称来解释表达式用途
if ((platform.toUpperCase().indexOf("MAC") > -1) && (browser.toUpperCase().indexOf("IE") > -1) && wasInitialized() && resize > 0) {// do something } final boolean isMacOs = platform.toUpperCase().indexOf("MAC") > -1; final boolean isIEBrowser = browser.toUpperCase().indexOf("IE") > -1; final boolean wasResized = resize > 0; if (isMacOs && isIEBrowser && wasInitialized() && wasResized) {// do something }复制代码
使用卫语句替代嵌套条件判断
把复杂的条件表达式拆分成多个条件表达式 , 减少嵌套 。嵌套了好几层的if - then-else语句 , 转换为多个if语句
//未使用卫语句public void getHello(int type) {if (type == 1) {return;} else {if (type == 2) {return;} else {if (type == 3) {return;} else {setHello();}}}} //使用卫语句public void getHello(int type) {if (type == 1) {return;}if (type == 2) {return;}if (type == 3) {return;}setHello();}复制代码
使用多态替代条件判断断
当存在这样一类条件表达式 , 它根据对象类型的不同选择不同的行为 。可以将这种表达式的每个分支放进一个子类内的复写函数中 , 然后将原始函数声明为抽象函数 。
public int calculate(int a, int b, String operator) {int result = Integer.MIN_VALUE;if ("add".equals(operator)) {result = a + b;} else if ("multiply".equals(operator)) {result = a * b;} else if ("divide".equals(operator)) {result = a / b;} else if ("subtract".equals(operator)) {result = a - b;}return result;}复制代码
当出现大量类型检查和判断时 , if else(或)语句的体积会比较臃肿 , 这无疑降低了代码的可读性 。另外 , if else(或)本身就是一个“变化点” , 当需要扩展新的类型时 , 我们不得不追加if else(或)语句块 , 以及相应的逻辑 , 这无疑降低了程序的可扩展性 , 也违反了面向对象的开闭原则 。
基于这种场景 , 我们可以考虑使用“多态”来代替冗长的条件判断 , 将if else(或)中的“变化点”封装到子类中 。这样 , 就不需要使用if else(或)语句了 , 取而代之的是子类多态的实例 , 从而使得提高代码的可读性和可扩展性 。很多设计模式使用都是这种套路 , 比如策略模式、状态模式 。
public interface Operation { int apply(int a, int b); }public class Addition implements Operation { @Override public int apply(int a, int b) { return a + b; } }public class OperatorFactory {private final static Map operationMap = new HashMap<>();static {operationMap.put("add", new Addition());operationMap.put("divide", new Division());// more operators}public static Operation getOperation(String operator) {return operationMap.get(operator);}}public int calculate(int a, int b, String operator) {if (OperatorFactory .getOperation == null) {throw new IllegalArgumentException("Invalid Operator");}return OperatorFactory .getOperation(operator).apply(a, b);}复制代码