重构改善既有代码设计--重构手法07:Remove Assignments 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的对象作为参数传给某个函数,那么“对参数赋值”意味着改变foo,使它引用另外一个对象。如果你在“被传入对象”身上进行什么操作,那没什么问题。这里只针对“foo被改而指向另一个对象”这种情况来讨论。

 

 Void aMethod(Object    foo)

{

      Foo.ModifyInSomeWay();

      Foo=anotherObject;

}

 

这样的做法降低了代码的清晰度,而且混用了按值传递和按引用传递这2种参数传递方式。

       在按值传递的情况下,对参数的任何修改,都不会对调用端造成任何影响。那些用过按引用传递方式的人可能会在这一点上犯糊涂。

       另一个让人糊涂的地方时函数本体内。如果你只以参数表示“被传递进来的东西”。那么代码会清晰地多,因为这种用法在所有语言都表现出相同语义。

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

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

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

       4、编译、测试。如果代码的语义是按引用传递的,请在调用端检查调用后是否还使用了这个参数,也要检查有多少个按引用传递的参数被赋值后又被调用。请尽量只以rteturn方式返回一个值。如果需要发挥的值不止一个,看看可否把需返回的大堆数据变成单一对象,或干脆为每个返回值设计对应的一个单独函数。

 

总结:一句话,就是对于传进来的参数如果是传值方式,不要直接对参数在代码函数中赋值,因为这种赋值其有效域就在本身这个函数中,为此通常我们将参数前面都加上final,防止其对参数进行赋值,一般都用临时变量代替,一旦产生临时变量就可以采用前面的技巧了。

posted on 2017-09-14 22:36  pony1223  阅读(404)  评论(0编辑  收藏  举报

导航