Remove Assignment to Parameters(移除对参数的赋值动作)

int discount(int inputVal, int quantity, int yearToDate) {
    if(inputVal > 50) inputVal -= 2;
==〉

int discount(int inputVal, int quantity, int yearToDate) {
    int result = inputVal;
    if(inputVal > 50) result -= 2;

 

动机:

 

我只针对[foo被改而指向(引用)完全不同的另一个对象]这种情况来讨论:
    void aMethod(Object foo) {
       foo.modifyInSomeWay();   //that's OK
       foo = anotherObject;   //throuble and despair will follow you
    }
我之所以不喜欢这样的作法,因为它降低了代码的清晰度,而且混淆了pass by value(传值)和pass by reference(传址)这两种参数传递方式。Java只采用pass by value传递方式,我们的讨论也正是基于这一点。

在pass by value情况下,对参数的任何修改,都不会调用端造成任何影响。那些用过pass by reference的人可能会在这一点上犯糊涂。

 

作法:

1 建立一个临时变量,把待处理的参数值赋予它。

2 以[对参数的赋值动作]为界,将其后所有对此参数的引用点,全部替换为[对此临时变量的引用动作]。

3 修改赋值语句,使其改为对新建之临时变量赋值。

4 编译,测试

 

如果代码的语义是pass by reference,请在调用端检查调用后是否还使用了这个参数。也要检查有多少个pass by reference参数[被赋值后又被使用]。请尽量只以return方式返回一个值。如果需要返回的值不只一个,看看可否把需返回的大堆数据变成单一对象,或干脆为每个返回值设计对应的一个独立函数。

 

int discount(int inputVal, int quantity, int yearToDate) {
    if(inputVal > 50) inputVal -= 2;
    if(quantity > 100) inputVal -= 1;
    if(yearToDate > 1000) inputVal -= 4;
    return inputVal;
}

 

以临时变量取代对参数的赋值动作,得到下列代码:

int discount(int inputVal, int quantity, int yearToDate) {
    int result = inputVal;
    if(inputVal > 50) result -= 2;
    if(quantity > 100) result -= 1;
    if(yearToDate > 1000) result -= 4;
    return result
}

还可以为参数加上关键词final,从而强制它遵循[不对参数赋值]这一惯例:

int discount(final int inputVal, final int quantity, final int yearToDate) {
    int result = inputVal;
    if(inputVal > 50) result -= 2;
    if(quantity > 100) result -= 1;
    if(yearToDate > 1000) result -= 4;
    return result
}

 

不过我的承认,我并不经常使用final来修饰参数,因为我发现,对于提高短函数的清晰度,这个办法并无太大帮助。我通常会在较长的函数中使用它,让它帮助我检查参数是否被做了修改。

 

 

你可能感兴趣的:(重构方法)