您的位置:首页 > 编程语言

重构-改善既有的代码设计(五)

2016-09-28 17:58 369 查看

1. 简化条件表达式

1.1 Decompose Conditional(分解条件表达式)

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

动机

复杂的条件逻辑使得代码的可读性大大降低。

做法

- 将if段落提炼出来,构成一个独立函数。

- 将then段落和else段落都提炼出来,各自构成一个独立函数。

范例:略。

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

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

动机

检查条件不同,最终行为却一致。

做法

- 确定这些条件语句都没有副作用。

- 使用适当的逻辑操作符,将一系列相关条件表达式合并为一个。

- 编译,测试。

- 对合并后的条件表达式实施Extract Method。

范例:略。

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

在条件表达式的每一个分支上有着相同的一段代码。将这段重复代码搬移到条件表达式之外。

动机

一组条件表达式的所有分支都执行了相同的某段代码。

做法

- 鉴别出执行方式不随条件变化而变化的代码。

- 如果这些共同代码位于条件表达式起始处,就将它移到条件表达式之前。

- 如果这些共同代码位于条件表达式尾端,就将它移到条件表达式之后。

- 如果这些共同代码位于条件表达式中段,就需要观察共同代码之前或之后的代码是否改变了什么东西。如果的确有所改变,应该首先将共通代码向前或向后移动,移至条件表达式的起始处或尾端,再以前面说的办法来处理。

- 如果共通代码不止一条语句,应该首先使用Extract Method将共通代码提炼到一个独立函数中,再以前面所说的办法来处理。

范例:略。

1.4 Remove Control Flag(移除控制标记)

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

动机

程序中加入了某些控制标记,大大降低条件表达式的可读性。

做法

- 找出让你跳出这段逻辑的控制标记值。

- 找出对标记变量赋值的语句,代以恰当的break语句或continue语句。

- 每次替换后,编译并测试。

范例:略。

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

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

动机

如果条件分支都是正常行为,就应该使用if…else…。如果某个条件极其罕见,就应该单独检查该条件。

做法

- 对于每一个检查,放进一个卫语句。

- 每次将条件检查替换成卫语句后,编译并测试。

范例:略。

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

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

动机

你需要根据对象的不同类型而采取不同的行为。

做法

- 如果要处理的条件表达式是一个更大函数的一部分,首先对条件表达式进行分析,然后使用Extract Method将它提炼到一个独立函数去。

- 如果有必要,使用Move Method将条件表达式放置到继承结构的顶端。

- 任选一个子类,在其中建立一个函数,使之覆写超类中容纳条件表达式的那个函数。将与子类相关的条件表达式分支复制到新建函数中,并对它进行适当调整。

- 编译,测试。

- 在超类中删掉条件表达式内被复制了的分支。

- 编译,测试。

- 针对条件表达式的每个分支,重复上述过程,直到所有分支都被移到子类内的函数为止。

- 将超类之中容纳条件表达式的函数声明为抽象函数。

范例:略。

1.7 Introduce Null Object(引入Null对象)

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

动机

你需要大量判断对象是否为null时。

做法

- 为源类建立一个子类,使其行为就像是源类的null版本。在源类和null子类中加入isNull()函数,前者的isNull()应该返回false,后者的isNull()应该返回true。

- 编译。

- 找出所有索求源对象却获得一个null的地方。修改这些地方,使它们该而获得一个空对象。

- 找出所有将源对象与null作比较的地方。修改这些地方,使它们调用isNull()函数。

- 编译,测试。

- 找出这样的程序点:如果对象不是null,做A动作,否则做B动作。

- 对于每一个上述地点,在null类中覆写A动作,使其行为和B动作相相同。

- 使用上述被覆写的动作,然后删除对象是否等于null的条件测试。编译并测试。

范例:略。

1.8 Introduce Assertion(引入断言)

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

动机

断言可以作为交流与调试的辅助。在交流的角度上,断言可以帮助程序阅读者理解代码所做的假设;在调试的角度上,断言可以在距离bug最近的地方抓住他们。

做法

- 如果你发现代码假设某个条件始终为真,就加入一个断言明确说明这种情况。

范例:略。

本文引用自图灵程序设计丛书:重构 改善改善既有的代码设计。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计 重构