重构之以函数对象取代函数(Replace Method With Method Object)
当我们把一个业务的逻辑都写在一个函数里面的时候,函数会很长很长;而在函数里面临时变量是必不可少的,而且还可能会存在很多很多个临时变量。这时我们要想重构这个函数是非常困难且耗时的,而且重构出来后的结果也会不理想;因为函数长必然处理逻辑多,逻辑多就代表着要分解的函数多,分解的函数多代表着类承担的职责就多了,这是个很不好的行为(至于为什么以后会提到,现在我们暂时先不管这个)。 哪当我们要对这样的函数进行重构时,该怎么做呢?什么又叫做“以函数对象取代函数(Replace Method With Method Object)”的重构手法呢?我们先来看看一段代码class Account
{
public 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;
}
/// <summary>
/// 这个是我偷懒写的一个函数
/// </summary>
/// <returns></returns>
public int delta()
{
/*此处应是一系列逻辑运算*/
return 1;
}
}
我们定义了一个类,类里面存在一个gamma()函数;从上面的代码我们可以看到gamma()函数既有参数传递进来,又存在了很多临时变量,临时变量里面的逻辑处理还要调用别的函数;gamma()函数处理的事情非常多,我们要进行提练函数(extract method)也并不好提取。
我们该怎么做呢???我们该怎么做呢???我们该怎么做呢???
首先,函数对象,函数对象嘛,必须要要一个类才能new一个对象啊!你都没有男(女)朋友怎么有对象呢?是吧!!!同样的你都不存在类怎么能new一个对象呢?所以我们第一步要做的就是先新建一个类,建立一个构造函数,把所有原函数的参数当做构造函数的参数。
class Gamma
{
private Account _account;
private int inputVal;
private int quantity;
private int yearToDate;
private int importantValue1;
private int importantValue2;
private int importantValue3;
public Gamma(Account source,int inputValArg,int quantityArg,int yearToDateArg)
{
_account = source;
inputVal = inputValArg;
quantity = quantityArg;
yearToDate = yearToDateArg;
}
}
细心的你会发现,怎么会多传了一个Account类的实例呢?看下去你自然会明白。
新类建好了,接下来我们要做的事就是把Account类里面的原函数复制到新类Gamma里面,然后改正代码错误,相信这难不倒聪明的你;
public int compute()
{
importantValue1 = (inputVal * quantity) + _account.delta();
importantValue2 = (inputVal*yearToDate) + 100;
if ((yearToDate-importantValue1)>1000)
{
importantValue2 -= 20;
}
int importantValue3 = importantValue2 * 7;
return importantValue3 - 2 * importantValue1;
}
最后我们就可以对compute()函数进行提取,把Account类的原函数改成调用新类Gamma的compute()函数。重构后的代码如下
class Account
{
public int gamma(int inputVal, int quantity, int yearToDate)
{
return new Gamma(this, inputVal, quantity, yearToDate).compute();
}
/// <summary>
/// 这个是我偷懒写的一个函数
/// </summary>
/// <returns></returns>
public int delta()
{
/*此处应是一系列逻辑运算*/
return 1;
}
}
class Gamma
{
private Account _account;
private int inputVal;
private int quantity;
private int yearToDate;
private int importantValue1;
private int importantValue2;
private int importantValue3;
public Gamma(Account source, int inputValArg, int quantityArg, int yearToDateArg)
{
_account = source;
inputVal = inputValArg;
quantity = quantityArg;
yearToDate = yearToDateArg;
}
public int compute()
{
importantValue1 = (inputVal * quantity) + _account.delta();
importantValue2 = (inputVal * yearToDate) + 100;
importantThing();
return importantValue2 * 7 - 2 * importantValue1;
}
public void importantThing()
{
if ((yearToDate - importantValue1) > 100)
{
importantValue2 -= 20;
}
}
}
相信看了重构后的代码你也应该知道为什么要传入一个Account类的实例了。
参考文献
重构——改善既有代码的设计 【美】Martin Fowler 著
熊节 译
你这个重构系列的教程不错哟 ibcadmin 发表于 2019-3-5 14:52
你这个重构系列的教程不错哟
:lol:lol:lol:lol
页:
[1]