重构第七章
2.Move Field(搬移值域)
你的程序中,某个field(值域)被其所驻之外的另一个class更多的用到。在target class中建立一个新的field(值域),修改source field的所有用户,领他们使用新的field。
Example:
class Account...
private AccountType _type;
private double _interestRate;
double interestForAmount_days(double amount, int days) {
return _interestRate*amount*days/365;
}
Analyse:
考虑到要将_interestRate移动到AccountType这个target class中,可以先将_interestRate移动过去。同时,Account class中使用到—_interesetRate的地方,可以通过AccountType类型的_type成员变量去访问。
End:
class AccountType...
private double _interestRate;
void setInterestRate(double arg) {
_interestRate = arg;
}
double getInterestRate() {
return _interestRate;
}
class Account...
double interestQForAmount_days(double amount, int days) {
return _type.getInterestRate()*amount*days/365;
}
以上方法是在Move Field(搬移值域)的调用点比较少的情况下使用的,如果Move Field(搬移值域)的引用点很多,需要使用Self-Encapsulation(自我封装)先做处理。
Self-Encapsulation(自我封装)
如果很多地方已经使用了_interestRate field,首先使用Self-Encapsulation(自我封装),为访问_interestRate field提供一个方法,其他地方调用自身提供的这个方法。这样,Move Field(搬移值域)之后,我们只需要修改这个访问方法就好了
Example:
class Account:
private AccountType _type;
private double _interestRate;
double interestForAmount_days(double amount, int days) {
return _type.getInterestRate()*amount*days/365;
}
private void setInterestRate(double arg) {
_interestRate = arg;
}
private double getInterestRate() {
return _interestRate;
}
Analyse:
我们首先可以先将需要Move Field(搬移值域)的field在source class中通过一个方法提供修改和访问的函数,然后修改其所有的引用点,之后使用Move Field(搬移值域)方法后,可以只修改source class中提供的修改和访问的方法。减少之后由于业务或者其他因素,导致需要访问其他class的Field的时候修改的工作量。
同时,使用Self-Encapsulation(自我封装)后,如果引用了搬移Field的引用点需要使用Move Method(搬移方法)的重构手法时,其引用点的值不需要修改。
End:
double interestForAmount_Days(double amount, int days) {
return getInterestRate()*amount *days/365;
}
private void setInterestRate(double arg) {
_type.setInterestRate(arg);
}
private double getInterestRate() {
return _type.getInterestRate();
}
Conclusion:
Move Field(搬移值域)和Move Method(搬移函数)很有可能在一次重构中同时进行,由于如果需要搬移的函数和特性联系比较紧密的时候,两种方法需要同时使用。在使用这两种方法之前,可以首先使用Self-Encapsulation(自我封装)修改代码的结构,使得之后的进行更加的顺畅。
注意
重构必须在有单元测试的情况下,保证之前的功能修改后不收影响。切记!!!
网友评论