1. 问题及方案
- 函数名称不清晰:Rename Method;
- 参数不明确:Add Parameter、Remove Parameter;
- 参数过多:Preserve Whole Object、Introduce Parameter Object;
- 函数参数来自该函数可以获取的对象:Replace Parameter with Method;
- 参数被用于条件表达式:Replace Parameter with Explicit Method;
- 多个相似函数添加参数:Parameterize Method;
- 查询命令函数分离:Separate Query from Modifier;
- 不必要的暴露:Hide Method、Remove Setting Method;
- 隐藏创建对象:Replace Constructor with Factory Method;
- 转型:Encapsulate Downcast;
- 错误码、异常、测试:Replace Error Code with Exception、Replace Exception with Test;
2. Rename Method(函数改名)
修改函数名称,更加清晰明了。
3. Add Parameter(添加参数)
为函数添加参数,带进所需信息。
3.1 动机
请先确认是否一定需要添加新参数:
- 你能从已有参数得到所需信息么?
- 有可能通过某个函数得到所需信息么?
- 这个函数是否应该属于拥有该信息的对象所有?
- 现有参数过多,是否考虑使用 Introduce Parameter Object?
ps
:若旧函数是接口一部分,不好删除,请标记为 deprecated(不赞成)。
4. Remove Parameter(移除参数)
将不需要的参数移除。
5. Separate Query from Modifer(将查询函数和修改函数分离)
建立两个不同的函数,一个负责查询,另一个负责修改。
5.1 动机
- 明确表示“有副作用”和“无副作用”两种函数之间的差异;
- 任何有返回值的函数,都不应该有看得到(提取出查询函数,将结果缓存到某个字段)的副作用。
ps
:多线程环境下,建立第三个函数来做“查询-修改”,该还是调用独立的查询函数和修改函数,并被声明为 synchronized。若为声明为 synchronized,则将它们的可见范围限制在包级别或 private 级别。如此就能保证安全、同步的操作。
6. Parameterize Method(令函数携带参数)
建立单一函数,以参数表达那些不同的值。
6.1 动机
多个函数处理类似工作,仅因为值不同而略有不同。
7. Replace Parameter with Explicit Methods(以明确函数取代参数)
问题:函数完全取决于参数值而采取不同行为。
针对该参数的的每一个可能值,建立一个独立函数。ps
:
- 与 Parameterize Method 正好相反。
- 若参数值对函数行为没太多影像,就不该使用该重构手法。
- 若需要条件判断,考虑使用 Replace Conditional with Polymorphism。
8. Preserve Whole Object(保持对象完整)
将从某个对象取出某些值作为参数传递改为直接传递整个对象。ps
:
- 两面性,该重构手法会产生依赖关系,请考虑后在使用。
- 先考虑 Move Method。
9. Replace Parameter with Methods(以函数取代参数)
问题:对象调用某个函数,并将所得结果作为参数,传递给另一个函数。而接受该参数的函数本身也能调用前一个函数。
让参数接受者去除该项参数,直接调用前一个函数。
9.1 动机
如果函数可以通过其他途径获取参数,就不应该通过参数传递。应尽可能缩短参数列的长度。
10. Introduce Parameter Object(引入参数对象)
以一个对象取代这些参数。
10.1 动机
特定的一组参数总是被一起传递,好几个函数都使用这组参数。这就是所谓的 Data Clumps(数据泥团)。
11. Remove Setting Method(移除设值函数)
若某个字段在对象创建后就不再改变,则应移除该字段的所有设值函数。
12. Hide Method(隐藏函数)
该函数不被外界使用,请设为 private。
13. Replace Constructor with Factory Method(以工厂函数取代构造函数)
将构造函数替换为工厂函数。
13.1 动机
- 在派生类中以工程函数取代类型码;
- 以明确函数创建子类;
14. Encapsulate Downcast(封装向下转型)
将向下转型动作移到函数中。
15. Replace Error Code with Exception(以异常取代错误码)
某个函数返回一个特定的代码,用以表示某种错误情况。改用异常。
16. Replace Exception with Test(以测试取代异常)
问题:面对一个调用者可以预先检查的条件,你抛出了一个异常。
修改调用者,使它在调用函数之前先做检查。
16.1 动机
- 异常滥用情况,异常只应该被用于意料之外的错误行为,而不应该成为条件检查的替代品。
ps
:我自己的坏习惯就是滥用异常,而且统一捕获。
参考
- 《重构-改善既有代码的设计》(第10章)