首页 > 代码库 > 重构笔记——以函数对象取代函数
重构笔记——以函数对象取代函数
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42549977
在上一篇文章中介绍了“移除对参数的赋值“。本文将介绍“以函数对象取代函数”这种重构手法。
下面让我们来学习这种重构手法吧。
开门见山
发现:你有一个大型函数,其中对局部变量的使用使你无法采用“提炼函数”这种重构手法。
解决:将这个函数放进一个单独对象中,这样,局部变量就成了对象的字段,然后就可以在同一个对象中将这个大型函数分解为多个小型函数。
//重构前 class Order.... double price(){ double basePrice; double secondaryPrice; double thirdaryPrice; //compute() ...... }<
//重构后 class Order... double price(){ return new PriceCalculator(this).compute(); } class PriceCalculator{ double basePrice; double secondaryPrice; double thirdaryPrice; double compute(){ //... } }
动机
在前面的文章中一直在强调小型函数的优美动人。只要将相对独立的代码从大函数提炼出来,就可以大大提高代码的可读性。
但是,局部变量的存在会增加函数分解的难度。如果一个函数中的局部变量泛滥成灾,那么想分解这个函数是非常困难的。“以查询替换临时变量”手法可以帮助减轻负担,但有时候还是会发现根本无法拆解一个需要拆解的函数。这种情况就应该考虑使用函数对象来解决。本文的重构方法会将所有的局部变量都变成函数对象的字段。然后就可以使用“提炼函数”创造新的函数,从而将原来的大型函数拆解变小。
做法
示例
class Account{ int gamm(int value, int quantity, int year2Date){ int importValue1 = (value * quantity) + delta(); int importValue2 = (value * year2Date) + 200; if(year2Date - importValue1 >200) importValue2-=50; int importValue3 = importValue2 * 8; //...... return importValue3 - 2 * importValue1; } //..... }为了把这个函数变为函数对象,首先需要声明一个新类。在新类中提供final对象保存原对象,对于函数的每个参数和每个临时变量,也以一个字段逐一保留。
class Gamm{ private final Account _account; private int value; private int quantity; private int year2Date; private int importValue1; private int importValue2; private int importValue3;接下来,加入一个构造函数。
Gamm(Account source, int inputVal, int quantity, int year2Date){
this._account = source;
this.value = http://www.mamicode.com/inputVal;> 现在可以把原本函数搬到compute()中了。函数中任何调用Accout类的地方,都必改用_account字段。
int compute(){ importValue1 = (value * quantity) + _account.delta(); importValue2 = (value * year2Date) + 200; if(year2Date - importValue1 >200) importValue2-=50; importValue3 = importValue2 * 8; //...... return importValue3 - 2 * importValue1; }然后,修改旧函数,让它将工作委托给刚完成的这个函数对象。
int gamm(int value, int quantity, int year2Date){ return new Gamm(this,value,quantity,year2Date).compute(); }以上就是本文重构方法的基本原则。其所带来的好处是:现在可以轻松地对compute()函数采取“提炼函数”,而不必担心参数传递的问题。
//运用提炼函数 不必担心参数问题 int compute(){ importValue1 = (value * quantity) + _account.delta(); importValue2 = (value * year2Date) + 200; importantThing(); importValue3 = importValue2 * 8; //...... return importValue3 - 2 * importValue1; } private void importantThing() { if(year2Date - importValue1 >200) importValue2-=50; }
重构笔记文章如下
重构笔记——入门篇
重构笔记——代码的坏味道(上)
重构笔记——代码的坏味道(下)
重构笔记——构筑测试体
重构笔记——提炼函数
重构笔记——内联函数
重构笔记——内联临时变量
重构笔记——以查询取代临时变量
重构笔记——引入解释性变量
重构笔记——分解临时变量
重构笔记——移除对参数的赋值重构笔记——以函数对象取代函数