1 Decompose Conditional(分解条件表达式)
从复杂表达式if-then-else三个段落中分别提炼出独立函数。
Motivation:降低表达式逻辑复杂度,突出分支作用。
做法:
- 将if段落提炼出来,构成一个独立函数。
- 将then段落和else段落都提炼出来,各自构成一个独立函数。
2 Consolidate Conditional Expression(合并条件表达式)
一系列条件表达式,得到的结果相同。将这些测试合并为一个条件表达式,并将这个条件表达式提炼成一个独立函数。
Motivation:合并多个并列条件成一个明确的条件审查可以使检查用意更清楚;这项重构可以为Extract Method做准备。
- 确定这些条件语句都没有副作用。
- 使用恰当的逻辑操作符,将一系列相关条件表达式合并为一个。
- 编译,测试。
- 对合并后的条件表达式使用Extract Method。
3 Consolidate Duplicate Conditional Fragments(合并重复条件片段)
在条件表达式中有相同代码,将代码提取到条件表达式之外。
4 Remove Control Flag(移除控制标记)
在一系列布尔表达式中,某个变量带有控制标记作用,以break或return取代控制标记。
Motivation:用break和continue语句的原因是用它们跳出复杂的条件语句可以使条件变得清晰得多。
做法:
- 找出让你跳出这段逻辑的判断标记。
- 找出对标记变量赋值的语句,替代以恰当的break语句或continue语句。
- 每次替换后,编译并测试。
5 Replace Nested Conditional with Guard Clauses(以卫语句取代嵌套条件表达式)
条件逻辑使人难以看清正常的执行路径。使用卫语句表现所有你特殊情况。
Motivation:条件表达式一共有两种形式:1.所有分支都属于正常行为。2.条件表达式提供的答案中只有一种是正常行为,其他都不常见。如果分支都属于正常行为,使用if-else挺好的;如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立即返回。这样单独的检查常常被称为“卫语句”。卫语句的精髓在于给一条分支以特别的重视。
- 对于每个检查,放进一个卫语句。ps:卫语句要么就从函数中返回,要不就抛出一个异常。
- 每次讲条件检查替换成卫语句后,编译并测试。
6 Replace Conditional with Polymorphism(以多态取代条件表达式)
有根据类型字段来选择函数不同的函数行为。将这个条件表达式的每个分支放进一个子类内的覆写函数中,然后将原始函数声明为抽象函数。
Motivation:使用条件表达式,使用的是硬编码,很难对条件表达式进行变化。
做法:
在做这个重构首发之前,必须得有继承结构,这种继承结构有两种手段去建立:Replace Type Code with Subclasses 和 Replace Type Code with State/Strategy。
- 如果要处理的条件表达式是一个更大函数中的一部分,首先对条件表达式进行分析,然后使用extract Method把它提炼到一个独立函数中。
- 如果有必要,使用Move Method将条件表达式放置到继承结构的顶端。
- 任选一个子类,在其中建立一个函数,使之覆写超类中容纳条件表达式的那个函数。将与该子类先关的条件表达式分支赋值到新建函数中,并对它进行适当调整。
- 编译,测试。
- 在超类删除到表达式内被赋值的分支。
- 编译,测试。
- 重复上述的过程,知道所有分支都被移动到子类内。
- 将超类之中容纳条件表达式的函数声明为抽象函数。
7 Introduce Null Object(引入Null对象)
你需要再三检查某对象是否为null。将null值替换为null对象。
Motivation:这是践行多态的一个非常好的方案。试想,如果对每个对象,都必须判断其是否为null,然后才能进行下一步的行为。那么系统中一定会运行大量的判断代码,这是就大量的重复代码。
做法:
- 为源类建立一个子类,使其行为就像源类的null版本。在源类和null子类中都加上isNull(),前者返回false,后者返回true。
- 编译。
- 找出所有索求源对象却获得一个null的地方。修改这些地方,使它们调用isNull()函数。
- 编译,测试。
- 找出这样的程序点:如果对象不是null,做A动作,否则B动作。
- 对于每一个上述弟弟昂,在null类中覆盖A动作,使其行为和B相同。
- 使用上述被覆写的动作,然后删除对象是否为null的条件测试。编译并测试。
tips:其实这样的方式可以被认为是特例类模式,用特例来减少处理特例的开销。
8 Introduce Assertion
用断言明确表明对程序状态的假设。
Motivation:可以帮助我们理解某些条件对程序是极其重要的。断言可以帮助程序阅读者阅读代码,可以帮助调试程序。
做法:
只要程序源不犯错,断言就应该不会对系统运行造成任何影响,所以加入断言永远不会影响程序的行为。断言一定要用来判断一定为真的条件。