Decompose Conditional(分解条件表达式)
- 现象:你有一个复杂的条件(if-then-else)语句
- 做法:从if,then,else三个段落中分别提炼出独立函数
- 复杂的条件逻辑是最常导致复杂度上升的地点之一
Consolidate Conditional Expression(合并条件表达式)
- 现象:你有一系列条件测试,都得到相同结果
- 做法:将这些测试合并为一个条件表达式,并将这个条件表达式提炼成为一个独立函数
- 如果你认为这些检查的确彼此独立,的确不应该被视为同一次检查,那么就不要使用本项重构。因为,这种情况下,你的代码已经清楚表达出自己的意义。
Consolidate Duplicate Conditional Fragments(合并重复的条件片段)
- 现象:在条件表达式的每个分支上有着相同的一段代码
- 做法:将这段重复代码搬移到条件表达式之外
Remove Control Flag(移除控制标记)
- 现象:在一系列布尔表达式中,某个变量带有“控制标记”(control flag)的作用
- 做法:以break语句或return语句取代控制标记
- “单一出口”原则会让你在代码中加入讨厌的控制标记,大大降低条件表达式的可读性。
- 另外一种方案:return语句
Replace Nested Conditional with Guard Clauses(以卫语句取代嵌套条件表达式)
- 现象:函数中的条件逻辑使人难以看清正常的执行路径
- 做法:使用卫语句表现所有特殊情况
- 卫语句:如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回
- 精髓:给某一条分支以特别的重视。if-then-else结构,各分支有同等重要性。
double getPayAmount() {
if (xxx) return xxx;
if (yyy) return yyy;
......
}
public double getAdjustedCapital() {
double result = 0.0;
if (_capital > 0.0) {
if (xxx) {
......
}
......
}
if (_capital <= 0.0) return result;
if (xxx) {
......
}
}
Replace Conditional with Polymorphism(以多态取代条件表达式)
- 现象:你手上有个条件表达式,它根据对象类型的不同而选择不同的行为。
- 做法:将这个条件表达式的每个分支放进一个子类内的覆写函数中,然后将源函数声明为抽象函数
Introduce Null Object (引入Null对象)
- 现象:你需要再三检查某对象是否为null
- 做法:将null值替换为null对象
- 多态的最根本好处在于:你不必再向对象询问“你是什么类型”而后根据得到的答案调用对象的某个行为–你只管调用该行为就是了,其他一切多态机制会为你安排妥当
Introduce Assertion(引入断言)
- 现象:某一段代码需要对程序状态做出某种假设
- 做法:以断言明确表现这种假设
- 断言是一个条件表达式,应该总是为真。如果它失败,表示程序员犯了错误
- 程序最后的成品往往将断言统统删掉
- 断言可作为交流与调试的辅助。在交流的角度上,断言可以帮助程序阅读者理解代码所做的假设;在调试的角度上,断言可以在距离bug最近的地方抓住它们。
- 注意,不要滥用断言。不要用它来检查“你认为应该为真”的条件,只用来检查“一定必须为真”的条件。如果断言所示约束条件不能满足,代码仍能正常运行,就把断言去掉。
- 可以新建一个Assert类,用于处理各种情况下的断言。