10 对函数调用重构

对函数调用重构

Rename Method(函数改名)

problem:函数的命名不能解释这个函数做什么
solution:重命名

1
2
3
4
5
getsnm(){}

//======================after refactoring=========================

getSecondName(){}

重构原因?

  1. 第一次创建方法太匆忙以至于没有很好地命名
  2. 随着功能的增加,函数名不足以很好的描述。

Add Parameter(增加参数)

problem:方法没有足够的数据来执行某些操作。
solution:创建一个新参数以传递必要的数据。

1
2
3
4
5
getContact();

//======================after refactoring=========================

getContact(Date);

重构原因?

函数需要新的数据来工作,相比增加一个私有字段,使用参数来传递数据更加合适。

Remove Parameter(移除参数)

problem:参数未在方法体中使用。
solution:删除未使用的参数。

1
2
3
4
5
getContact(Date);

//======================after refactoring=========================

getContact();

重构原因?

删除没有被使用到的参数

Separate Query from Modifier(分离查询和修改)

problem:一个函数既查询又修改
solution:将查询和修改的函数拆开

1
2
3
4
5
6
getTotalOutstandingAndSetReadyForSummaries();

//======================after refactoring=========================

getTotalOutstanding();
setReadyForSummaries();

重构原因?

让函数的功能更加明确

Preserve Whole Object(传递整个对象)

problem:从对象获取多个值,然后将它们作为参数传递给方法。
solution:相反,尝试传递整个对象。

1
2
3
4
5
6
7
int low = daysTempRange.getLow();
int high = daysTempRange.getHigh();
boolean withinPlan = plan.withinRange(low, high);

//======================after refactoring=========================

boolean withinPlan = plan.withinRange(daysTempRange);

重构原因?

当方法需要增加参数的时候,不需要修改每个调用它的地方。

改重构会导致该函数变得不够灵活,二思而后行。

Replace Parameter with Method Call(用方法的调用来代替参数)

problem:调用查询方法并将其结果作为另一个方法的参数传递,而后者可以直接调用查询。
solution:不要通过参数传递值,而是尝试在方法体内放置查询调用。

1
2
3
4
5
6
7
8
9
int basePrice = quantity * itemPrice;
double seasonDiscount = this.getSeasonalDiscount();
double fees = this.getFees();
double finalPrice = discountedPrice(basePrice, seasonDiscount, fees);

//======================after refactoring=========================

int basePrice = quantity * itemPrice;
double finalPrice = discountedPrice(basePrice);

重构原因?

简化函数调用

这种重构更多是考虑当下,而不是着眼未来。符合设计原则——you are’t not need it

Introduce Parameter Object(引入参数对象)

problem:方法包含重复的参数组。
solution:用对象替换这些参数。

1
2
3
4
5
6
7
8
9
fun1(Date start,Date end);
fun2(Date start,Date end);
fun2(Date start,Date end);

//======================after refactoring=========================

fun1(DateRange date);
fun2(DateRange date);
fun2(DateRange date);

重构原因?

多次使用同一组参数列表
日后可能还可以对这个重构对象增加一些行为。

Remove Setting Method(移除setter方法)

problem:字段的值只应在创建时设置,并且在此之后不能随时更改。
solution:删除设置字段值的方法。

Hide Method(隐藏方法)

problem:其他类不使用方法,或仅在其自己的类层次结构中使用该方法。
solution:使方法成为私有或受保护。

重构原因?

只让其它类看到具有完整功能的函数,至于如何实现这个函数的过程,不应该暴露出去。

Replace Constructor with Factory Method(使用简单工厂代替构造器)

problem:有一个复杂的构造函数,它不仅仅在对象字段中设置参数值。
solution:使用简单工厂来替换构造函数调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Employee {
Employee(int type) {
this.type = type;
}
//...
}

//======================after refactoring=========================

class Employee {
static Employee create(int type) {
employee = new Employee(type);
// do some heavy lifting.
return employee;
}
//...
}

重构原因?

使用简单工厂可以再创建对象的同时做更多的事情:

  1. 可以选择性的创建并返回子类对象
  2. 可以返回一个已经存在的对象(单例)
  3. 可以对解耦new关键字

Replace Error Code with Exception(用异常代替错误码)

problem:方法返回一个指示错误的特殊值
solution:应该抛出异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int withdraw(int amount) {
if (amount > _balance) {
return -1;
}
else {
balance -= amount;
return 0;
}
}

//======================after refactoring=========================

void withdraw(int amount) throws BalanceException {
if (amount > _balance) {
throw new BalanceException();
}
balance -= amount;
}

重构原因?

异常的出现就是解决不断地校验错误码来辨认调用成功还是失败的繁琐工作

本文标题:10 对函数调用重构

文章作者:Sun

发布时间:2019年01月15日 - 11:01

最后更新:2019年01月15日 - 20:01

原始链接:https://sunyi720.github.io/2019/01/15/refactoring/10 对函数调用重构/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。