Split Temporary Variable (分解临时变量)

Summary:

程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。针对每次赋值,创造一个独立、对应的临时变量。 java

Motivation:

临时变量有各类不一样用途,其中某些用途会很天然地致使临时变量被屡次赋值。“循环变量”和“结果收集变量”就是两个典型例子:循环变量(loop variable)会岁循环的每次运行而改变(例如for(int i=0; i<10; i++)语句中的i);结果收集变量(collecting temporary variable)负责将“经过整个函数的运算”而构成的某个值收集起来。 函数

除了这两种状况,还有不少临时变量用于保存一段冗长代码的运算结果,以便稍后使用。这种临时变量应该只被赋值一次。若是它们被赋值超过一次,就意味着它们在函数中承担了一个以上责任。若是临时变量承担多个责任,它就应该被替换(分解)为多个临时变量,每一个变量只承担一个责任。同一个变量承担两件不一样的事情,会令代码阅读者糊涂。 oop

Mechanics:

1.  在待分解临时变量的声明及其第一次被赋值处,修改其名称。 测试

       若是稍后之赋值语句是[i=i+某表达式],就意味着这是个结果收集变量,那么就不要分解它。结果收集变量的做用一般是累加、字符串接合、写入流或者向集合添加元素 spa

2. 将新的临时变量声明为final code

3.以该临时变量的第二次赋值动做为界,修改此前对该临时变量的全部引用点,让它们引用新的临时变量。 字符串

4.在第二次赋值处,从新声明原先那个临时变量。 get

5.编译,测试。 io

   6. 逐次重复上述过程。每次都在声明处对临时变量更名,并修改下次赋值以前的引用点。 编译

范例

下面的范例中,咱们计算一个苏格兰布丁运动的距离。在起点处,静止的苏格兰布丁会受到一个初始力的做用而开始运动。一段时间后,第二个力做用于布丁,让它再次加速。根据牛顿第二定律,咱们能够这样计算布丁运动的距离

double getDistanceTravelled( int time )
    {
        double result;
        double acc = primaryForce / mass;
        int primaryTime = Math.min( time, delay );
        result = 0.5 * acc * primaryTime * primaryTime;
        int secondaryTime = time - delay;
        if( secondaryTime > 0 )
        {
            double primaryVel = acc * delay;
            acc = ( primaryForce + secondaryForce ) / mass;
            result += primaryVel * secondaryTime + 
                      0.5 * acc * secondaryTime * secondaryTime;
        }
        return result;

    }

注意观察此例中的acc变量如何被赋值两次。acc变量有两个责任:第一是保存第一个力形成的初始加速度;第二是保存两个力共同形成的加速度。这就是咱们想要分解的东西。

首先,咱们在函数开始处修改这个临时变量的名称,并将新的临时变量声明为final。接着,我把第二次赋值以前对acc变量的全部引用点,所有改用新的临时变量。最后,咱们在第二次赋值处从新声明acc变量:

double getDistanceTravelled( int time )
    {
        double result;
        final double primaryAcc = primaryForce / mass;
        int primaryTime = Math.min( time, delay );
        result = 0.5 * primaryAcc * primaryTime * primaryTime;
        int secondaryTime = time - delay;
        if( secondaryTime > 0 )
        {
            double primaryVel = primaryAcc * delay;
            double acc = ( primaryForce + secondaryForce ) / mass;
            result += primaryVel * secondaryTime + 
                            0.5 * acc * secondaryTime * secondaryTime;
        }
        return result;
    }
新的临时变量的名称指出,它只承担原先acc变量的第一个责任。咱们将它声明为final,确保它只被赋值一次。而后,咱们在原先acc变量第二次被赋值处从新声明acc。如今,从新编译并测试,一切应该都没有问题。

而后,咱们继续处理acc临时变量的第二次赋值。此次咱们把原先的临时变量彻底删掉,代之以一个新的变量。新变量的名称指出,它只承担原先acc变量的第二个责任:

double getDistanceTravelled( int time )
    {
        double result;
        final double primaryAcc = primaryForce / mass;
        int primaryTime = Math.min( time, delay );
        result = 0.5 * primaryAcc * primaryTime * primaryTime;
        int secondaryTime = time - delay;
        if( secondaryTime > 0 )
        {
            double primaryVel = primaryAcc * delay;
            final double secondaryAcc = ( primaryForce + secondaryForce ) / mass;
            result += primaryVel * secondaryTime + 
                            0.5 * secondaryAcc * secondaryTime * secondaryTime;
        }
        return result;
    }
如今这段代码确定可让你想起更多的其余重构手法。
相关文章
相关标签/搜索