条件表达式重构
如何让条件语句看起来更清晰?
Decompose Conditional(分解条件式)
problem:你有一个复杂的条件(if-then-else)语句。
solution:从if、then、else 三个段落中分别提炼出独立函数。
1 | if (date.before (SUMMER_START) || date.after(SUMMER_END)) |
重构的原因?
程序之中,【复杂的条件逻辑】是最常导致复杂度上升的地点之一。
对于条件逻辑,【将每个分支条件分解,形成新函数】还可以给你带来更多好处:可以突出条件逻辑,更清楚地表明每个分支的作用,并且突出每个分支的原因。
Consolidate Conditional Expression(合并条件式)
problem:你有一系列条件测试,都得到【相同结果】。
solution:将这些测试合并为一个条件式,并将这个条件式提炼成为一个独立函数。
1 | double disabilityAmount() { |
重构的原因?
- 合并后的条件代码会告诉你【实际上只有一次条件检查,只不过有数个并列条件需要检查而已】,从而使这一次检查的用意更清晰。
- 【将检查条件提炼成一个独立函数】对于理解代码意义非常有用,因为它把描述【做什么】的语句换成了【为什么这样做】。
Consolidate Duplicate Conditional Fragments(合并重复的条件片段)
problem:在条件式的每个分支上有着相同的一段代码。
solution:将这段重复代码搬移到条件式之外。
1 | if (isSpecialDeal()) { |
重构的原因?
代码能更清楚地表明哪些东西随条件的变化而变化、哪些东西保持不变。
Remove Control Flag(移除控制标记)
problem:在一系列布尔表达式(boolean expressions)中,某个变量带有【控制标记】(control flag)的作用。
solution:以break语句或return的语句取代控制标记。
1 | void checkSecurity(String[] people) { |
重构的原因?
条件语句真正的用途会清晰得多
Replace Nested Conditional with Guard Clauses(以卫语句取代嵌套条件式)
problem:函数中的条件逻辑(conditional logic)使人难以看清正常的执行路径。
solution:使用卫语句(guard clauses)表现所有特殊情况。
1 | double getPayAmount() { |
什么是卫语句?
如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回。
这样的单独检查常常被称为【卫语句(guard clauses)】
重构的原因?
如果使用if-then-else 结构,你对if 分支和else 分支的重视是同等的。 这样的代码结构传递给阅读者的消息就是:各个分支有同样的重要性。卫语句(guard clauses)就不同了,它告诉阅读者:【这种情况很罕见,如果它真的发生了,请做 一些必要的整理工作,然后退出。】
Replace Conditional with Polymorphism(以多态取代条件式)
problem:你手上有个条件式,它根据对象型别的不同而选择不同的行为。
solution:将这个条件式的每个分支放进一个subclass内的覆写函数中,然后将原始函数声明为抽象函数(abstract method)。
该手法在Replace Type Code with State/Strategy中已经使用到。
重构的原因?
如果你需要根据对象的不同型别而采取不同的行为,多态使你不必编写明显的条件式
Introduce Null Object(引入Null对象)
你需要再三检查【某物是否为null value】。
将null value(无效值)替换为null object(无效物)。
重构的原因?
你不必再向对象询问「你是什么型别」 而后根据得到的答案调用对象的某个行为——你只管调用该行为就是了,其他的一切多态机制会为你安排妥当。
Null Object中需要对所有的行为都作出相应的响应,才不再需要作Null的判断。