Split Temporary Variable(剖解临时变量)

double temp = 2 * (_height + _widgth);
    System.out.println(temp);
    temp = _height * _widgth;
    System.out.println(temp);
==〉

final double perimeter = 2 * (_height + _widgth);
    System.out.println(perimeter);
    final double area = _height * _widgth;
    System.out.println(area);

 

 动机:

临时变量有各种不同用途,其中某些用途会很自然地导致临时变量被多次赋值。[循环变量]和[集用临时变量]就是两个典型例子:循环变量(loop variable)会随循环的每次运行而改变(例如for(int i=0; i <10;i++)语句中的i);集用临时变量(collection temporary variable)负责将[通过整个函数的运算]而构成的某个值收集起来。

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

 

作法:

1 在[待剖解]之临时变量的声明式及其第一次被赋值处,修改其名称。

 如果稍后之赋值语句是[i = i + 某表达式]形式,就意味这是个集用临时变量,那么就不要剖解它。集用临时变量的作用通常是累加、字符串接合、写入stream或者向群集(collection)添加元素。

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

3 以该临时变量之第二次赋值动作为界,修改此前对该临时变量的所有引用点,让它们引用新的临时变量。

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

5 编译,测试。

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变量有两个责任:第一是保存第一个力造成的初始加速度;第二是保存两个力共同造成的加速度。这就是我想要剖解的东西。


首先,我在函数开始处修改这个临时变量的名称,并将新的临时变量声明为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;
}


 以下是我自己对以上的代码进行的重构,未测试,仅供参考。

double getDistanceTravelled(int time) {

 GetDistance(time) + GetSecondDistance(time);

}

double GetDistance(int time)
{
 return 0.5 * GetPrimaryAcc()* GetPrimaryTime(time)* GetPrimaryTime(time);
}

double GetSecondDistance(int time)
{
 
    if(GetSecondTime(time)> 0) {
       return GetPrimaryAcc()* _delay * GetSecondTime(time)+
  0.5 * GetSecondAcc()* GetSecondTime(time)* GetSecondTime(time);
    }
 else
 {
  return 0;
 }
}

double GetPrimaryAcc()
{
 return _primaryForce / _mass;
}

double GetSecondAcc()
{
 return (_primaryForce + _secondaryForce) / _mass;
}

double GetPrimaryTime(int time)
{
 return Math.min(time, _delay);
}

double GetSecondTime(int time)
{
 return time - _delay;
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值