第9章 简化条件表达式

简介:

这章主要是讲解了怎样简化程序中的条件表达式,简化代码逻辑。

 

分解条件表达式(Decompose Conditional)

1.理解:

你有一个复杂的条件(if-then-else)语句,可以从if,then,else三个段落中分别提炼独立函数。

2.动机:

越来越多复杂的条件表达式,会增加阅读代码的难度。所以分解,提炼成多个独立函数是很有必要的。提炼出的函数根据每个小块代码用途来命名,清楚表达自己的意图。

3.做法:

类似“以查询替代临时变量”的方式,这里是以查询替代表达式。

 

合并条件表达式(Consolidate Conditional Expression)

1.概念:

你有一系列条件测试,都得到相同的结果。将这些测试合并为一个条件表达式,并将这个条件表达式提炼成为一个独立函数。

//合并前
double disabilityAmount() {
    if (seniority < 2) return 0;
    if (monthsDisabled > 12) return 0;
    if (isPartTime) return 0; 
}

//合并后
double disabilityAmount {
    if (isNotEligableForDisability()) return 0;
}

2.做法:

先将这些能合并的表达式合并,到底用提炼函数将它们提取到一个函数里,还是用一个完整表达式直接显示出来,视情况而定。

 

合并重复的条件片段(Consolidate Duplicate Conditional Fragments)

1.概念:

很好理解,顾名思义。

//合并前
if (isSpecialDeal()) {
    total = price * 0.95;
    send();
} else {
    total = price * 0.98;
    send();
}

//合并后
if (isSpecialDeal()) {
    total = price * 0.95;
} else {
    total = price * 0.98;
}
send();

 

移除控制标记(Remove Control Flag)

1.概念:

在一系列布尔表达式中,某个变量带有“控制标记”的作用,则以break语句或者return语句取代控制标记。

2.动机:

移除控制标记会使条件语句的用途更加清晰。

3.例子:

//改变前
public class ControlMark {
    public void checkSecurity(String[] people) {
        boolean found = false;
        for (int i = 0; i < people.length; i++) {
            if (!found) {
                if (people[i].equalsIgnoreCase("Don")) {
                    //do something
                    found = true;
                }
                if (people[i].equalsIgnoreCase("John")) {
                    //do something
                    found = true;
                }
            }
        }
    }

//改变后
    public String checkSecurityAfer(String[] people) {
        for (int i = 0; i < people.length; i++) {
            if (people[i].equalsIgnoreCase("Don")) {
                //do something
                return "Don";
            }
            if (people[i].equalsIgnoreCase("John")) {
                //do something
                return "John";
            }
        }
        return " ";
    }
}

 

以卫语句取代嵌套条件表达式(Replace Nested Conditional with Guard Clauses)

1.什么是卫语句:

卫语句就是把复杂的条件表达式拆分成多个条件表达式,比如一个很复杂的表达式,嵌套了好几层的if - then-else语句,转换为多个if语句,实现它的逻辑,这多条的if语句就是卫语句。

2.概念:函数中的条件逻辑使人难以看清正常的执行路径,使用卫语句表现所有特殊情况。

//改变前
public class ComplicatedClauses {
    public void soulStandard() {
        String soulmate = "";
        if ("boy".equalsIgnoreCase(soulmate)) {
            //not accept;
        } else if ("bad temperature".equalsIgnoreCase(soulmate)){
            //not accept;
        } else {
            if ("beauty".equalsIgnoreCase(soulmate)) {
                if ("nice smile".equalsIgnoreCase(soulmate)) {
                    //accept
                } else {
                    //not accept
                }
            }
        }
    }
}
//使用卫语句,改变后
public class ComplicatedClauses {
    public void soulStandard() {
        String soulmate = "";
       if ("boy".equalsIgnoreCase(soulmate)) {
            //not accept
        }
        if ("bad temperature".equalsIgnoreCase(soulmate)) {
            //not accept
        }
        if ("beauty".equalsIgnoreCase(soulmate) && "nice smile".equalsIgnoreCase(soulmate)) {
            //accept
        } else {
            //not accept
        }
    }
}

3.动机:

条件表达式通常有两种表达形式:

(1)所有分支都属于正常行为,用if...else...语句。

(2)条件表达式提供的答案中只有一种是正常行为,其他都是不常见的,用卫语句。

→其实“以卫语句取代嵌套条件表达式”方法的精髓就是,给某条分支以特别的重视,如果它真的发生了,请做一些必要整理工作,然后退出。if...then...else各分支的重视程度是相等的。

4.注意:

在以卫语句表达时,可以考虑将条件反转

//原式
if (result > 0) {
    ....
}
//改为
if (result <= 0) return result;

 

以多态取代条件表达式(Replace Conditional with Polymorphism)

1.概念:

你手上有个条件表达式,它根据对象类型的不同而选择不同的行为。将这个条件表达式的每个分支放进一个子类的覆写函数中,然后将原始函数声明为抽象函数。

//原式
public
double getSpeed() { switch (type) { case EUROPEAN: return getBaseSpeed(); case AFRICAN: return getBaseSpeed() - getLoadFactor() * numberOfCoconuts; case NORWEGIAN_BLUE: return (isNailed) ? 0 : getBaseSpeed(voltage); } throw new RuntimeException("Should be unreachable"); }

 

引入Null对象(Introduce Null Object)

1.概念:

你需要再三检查某对象是否为null,将null值替换为null对象。

2.疑问

将null替换为null对象,现在貌似没有看到这么做的了?

 

引入断言(Introduce Assertion)

1.概念:

某一段代码需要对程序状态做出某种假设。以断言明确表现这种假设。

2.经验:

目前经历中一般在测试类加,其他情况视情况而定。

posted @ 2020-08-26 11:23  pmingup9012  阅读(244)  评论(0编辑  收藏  举报