有一个大型函数,其中对局部变量的使用使你没法采用Extract Method。将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的字段。而后能够在同一个对象中将这个大型函数分解为多个小型函数。java
局部变量的存在会增长函数分解的难度。若是一个函数之中局部变量泛滥成灾,那么想分解这个函数是很是困难的。Replace Temp with Query能够帮助减轻这一负担,可是有时候根本没法拆解一个须要拆解的函数。这种状况下,就要用到函数对象(method object)这一法宝。函数
Replace Method with Method Object 会将全部局部变量都变成函数对象的字段而后能够对这个新对象使用Extract Method 创造出新函数,从而将本来的大型函数拆解变短。this
1. 创建一个新类,根据待处理函数的用途,为这个类命名spa
2. 在新类中创建一个final字段,用以保存原先大型函数所在的对象。咱们将这个字段称为“源对象”。同时,针对原函数的每一个临时变量和每一个参数,在新类中创建一个对应的字段保存之。code
3.在新类中创建一个构造函数,接受源对象及原函数的全部参数做为参数。对象
4.在新类中创建一个compute () 函数。input
5. 将原函数的代码复制到compute () 函数中。若是须要调用源对象的任何函数,请经过源对象字段调用。it
6. 编译io
7. 将旧函数的函数本体替换为这样一条语句:“建立上述新类的一个新对象,然后调用其中的compute () 函数”。编译
public 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; //and so on. return importantValue3 - 2 * importantValue1; } }
为了把这个函数变成一个函数对象,咱们须要首先声明一个新类。在此新类中咱们应该提供一个final字段用以保存源对象;对于函数的每个参数和每个临时变量,也以一个字段逐一保存。 为了保持小步前进,咱们暂时先保留这些字段的原名。而后,加入一个构造函数
class Gamma{ private final Account account; private int inputVal; private int quantity; private int yearToDate; private int importantValue1; private int importantValue2; private int importantValue3; Gamma( Account source, int inputValArg, int quantityArg, int yearToDateArg ) { account = source; inputVal = inputValArg; quantity = quantityArg; yearToDate = yearToDateArg; } }
如今能够把本来的函数搬到compute() 了。函数中任何调用Account类的地方,咱们都必须改而使用account字段。
int compute() { int importantValue1 = ( inputVal * quantity ) + account.delta(); int importantValue2 = ( inputVal * yearToDate ) + 100; if( ( yearToDate - importantValue1 ) > 100 ) { importantValue2 -= 20; } int importantValue3 = importantValue2 * 7; //and so on. return importantValue3 - 2 * importantValue1; }
而后,修改旧函数,让它将工做委托给刚完成的这个函数对象。
int gamma( int inputVal, int quantity, int yearToDate ) { return new Gamma(this, inputVal, quantity, yearToDate).compute(); }
这就是本项重构的基本原则。它带来的好处是:如今咱们呢能够轻松地对compute()函数采起Extract Method, 没必要担忧参数传递的问题。