做法
- 将if段落提炼出来,构成一个独立的函数
- 将then段落和else段落提炼出来,各自构成一个独立的函数。
将这些测试合并为一个条件表达式,并将这个条件表达式提炼成为一个独立函数
动机
- 一串条件检查,检查条件不一样,最终的行为却一致。
做法
-
确定这些条件语句没有副作用
如果条件表达式有副作用,你就不能使用本项重构。
-
使用适当的逻辑操作符,将一系列相关条件表达式合并为一个
-
编译,测试
-
对合并后的条件表达式实施Extract Method(10)
做法
- 鉴别出“执行方式不随条件变化而变化”的代码
- 如果这些共通代码位于条件表达式起始处,就将它移到条件表达式之前。
- 如果这些共通代码位于条件表达式尾端,就将它移到条件表达式之后。
- 如果这些共通代码位于条件表达式中段,就需要观察共同代码之前或之后的代码是否改变了什么。如果的确有所改变,应该首先将共同代码向前或向后移动,移至条件表达式的起始处或尾端。
- 如果共通代码不止一条语句,应该首先使用Extract Method(110)将共同代码提炼到一个独立的函数,再以前面所说的办法来处理。
以break语句或return语句取代控制标记
if (condition){
return
}
else if(condition) return
>>>
if (con) return ...
if (con2) return ...
9.6 Replace Conditional With Polymorphism(以多态取代条件表达式)
将这个条件表达式的每个分支放进一个子类内的覆写函数中,然后将原始函数声明为抽象函数
动机
多态的最根本的好处在于:你不必再向对象询问“你是什么类型”而后根据得到的答案调用对象的某个行为、
做法
-
为源类建立一个子类,使其行为就像是一个源类的null版本。在源类和null子类中都加上isNull()函数,前者的isNull()应该返回false,后者的isNull()返回true
- 建立一个nullable接口,将isNull()函数放在其中,让源类实现这个接口。
- 创建一个测试接口,专门用来检查对象是否为null。
-
编译
-
找出所有“索求源对象却获得一个null”的地方,修改这些地方,使他们改而获得一个空对象。
-
找出所有“将源对象与null做比较”的地方。修改这些地方,使他们调用isNull()函数。
- 可以每次只处理一个源对象及其客户程序,编译并测试后,在处理另一个源对象。
- 你可以在“不该再出现null”的地方放上一些断言,确保null的确不在出现。
-
编译测试。
-
找出这样的程序点,如果对象不是null,做A动作,否则做B动作。
-
对于每一个上述地点,在null类中覆写A动作,使其行为和B动作相同。
-
使用上述被覆写的动作,然后删除“对象是否等于null”的条件测试。编译并测试。
做法
- 加入断言不会影响程序的行为,如果代码假设某个条件始终为真,就加入一个断言明确说明这种情况。
- 注意不要滥用断言。不要使用它检查“你认为应该为真的”的条件,只检查“一定为真的”的条件。