标签:style blog http ar color sp strong on div
有时候,当你遇到一个大型函数,里面的临时变量和参数多的让你觉得根本无法进行Extract Method。重构中也大力的推荐短小函数的好处,它所带来的解释性,复用性让你收益无穷。但如果你遇到上种情况,你可能会天真的以为我只要适当的进行Replace Temp with Query,就可以把这种现象给化解。但情况往往事与愿违,不能达到你所理想的高度。这个时候你需要用到重构中的杀手锏--Replace Method with Method Object,这个手法出自Kent Beck [Beck]。
简单的说,这个重构会把源函数内的所有局部变量的参数都变成Method Object的字段。然后因为是字段,所以就不存在临时变量这个限制,你就可以轻轻松松的对新对象的新函数进行Extract Method将原来的大型函数进行轻松拆解。
做法:
完成这些之后,你就可以对新类中的compute()函数进行大刀阔斧的改造了。
例子:
class Account...
int gamma(int inputVal, int quantity, int yearToDate) { int importantValue1 = (inputVal * quantity) + delta(); int importantValue2 = (inputVal * yearToDate) + 100; if ((yearToDate - importantValue1) > 100) importantValue2 -= 20; int importantValue3 = importantValue2 * 7; return importantValue3 - 2 * importantValue1; }
这是我们的原函数,可以看到,参数和临时变量非常多,非常难以进行Extract Method。所以是时候用出我们的杀手锏,首先按照『做法』,我们新建一个新类,然后将这个函数的参数和临时变量都变成他的字段。
class Gamma { private: const Account *m_account; int inputVal; int quantity; int yearToDate; int importantValue1; int importantValue2; int importantValue3; };
为了保证重构的小步进行,这里我们不对字段变量进行任何改名,这样有其何处,当你将原函数的实现搬过来的时候,你暂时不需要进行任何修改。
接下来我们进行构造函数的声明,注意:这个时候你只需要将原函数的所在对象和所需参数当作构造函数参数即可,不需要所有的临时变量。
public: Gamma(Account *account, int inputValArg, int quantityArg, int yearToDateArg) : m_account(account), inputVal(inputValArg), quantity(quantityArg), yearToDate(yearToDateArg) { }
接下来,我们声明compute()函数,并且将原函数的实现搬过来,讲里面的声明删除,因为已经是新类的字段了,然后将对源对象本身的函数调用替换成对字段的调用,完整实现如下
class Gamma { public: Gamma(Account *account, int inputValArg, int quantityArg, int yearToDateArg) : m_account(account), inputVal(inputValArg), quantity(quantityArg), yearToDate(yearToDateArg) { } int compute() { importantValue1 = (inputVal * quantity) + m_account->delta(); importantValue2 = (inputVal * yearToDate) + 100; if ((yearToDate - importantValue1) > 100) importantValue2 -= 20; importantValue3 = importantValue2 * 7; return importantValue3 - 2 * importantValue1; } private: const Account *m_account; int inputVal; int quantity; int yearToDate; int importantValue1; int importantValue2; int importantValue3; };
注意,其中的delta()函数,此时已经变成了m_account->delta(),并且所有变量的声明都已经被删除。
完成了这一步之后,其实我们已经结束了本次重构手法,但还没完,我们之所以运用Replace Method with Method Object就是为了更好的进行Extract Method,所以接下来,我们就可以轻轻松松对新类新函数进行重构,比如
class Gamma... int compute() { importantValue1 = (inputVal * quantity) + m_account->delta(); importantValue2 = (inputVal * yearToDate) + 100; importThing(); return importantValue3 - 2 * importantValue1; } private: void importThing() { if ((yearToDate - importantValue1) > 100) importantValue2 -= 20; }
这样,我们就轻松做到了对compute()函数的无参化的Extract Method,整个实现更加简洁,不需要去担心参数传递的问题。
『重构--改善既有代码的设计』读书笔记----Replace Method with Method Object
标签:style blog http ar color sp strong on div
原文地址:http://www.cnblogs.com/rickyk/p/4156767.html