重构手法之Split Temporary Variable(分解临时变量)_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 重构手法之Split Temporary Variable(分解临时变量)

重构手法之Split Temporary Variable(分解临时变量)

 2017/11/20 10:18:23  NaYoung  程序员俱乐部  我要评论(0)
  • 摘要:返回总目录本小节目录SplitTemporaryVariable(分解临时变量)RemoveAssignmentstoParameters(移除对参数的赋值)6.6SplitTemporaryVariable(分解临时变量)概要你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。针对每次赋值,创造一个独立、对应的临时变量。动机临时变量有各种不同的用途。1、循环变量;2、结果收集变量;3、保存一段冗长代码的运算结果,便于稍后使用
  • 标签:ORA RIA

返回总目录

本小节目录

  • Split Temporary Variable(分解临时变量)
  • Remove Assignments to Parameters(移除对参数的赋值)

6.6Split Temporary Variable(分解临时变量)

概要

你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果。

针对每次赋值,创造一个独立、对应的临时变量。

动机

临时变量有各种不同的用途。

1、循环变量;

2、结果收集变量;

3、保存一段冗长代码的运算结果,便于稍后使用。

其中第三种情况的临时变量应该只被赋值一次。如果它们被赋值超过一次,就意味着它们在函数中承担了一个以上的责任。如果临时变量承担了多个责任,它就应该被分解为多个临时变量,每个变量只承担一个责任。同一个临时变量承担两件不同的事情,会令代码阅读者糊涂。

范例

double GetTotalCost()
{
    double result = 0;

    double money = _chickMoney + _chipMoney;

    result += money;

    money = _cocoaMoney + _coffeeMoney;

    result += money;

    return result;
}

可以看到在这个范例中,临时变量money被赋值两次。并且它没有做到累积结果的作用,累积结果给了result。所以,我们需要做重构,让这个变量的意图变的更加明确。

所以我们第一步,寻找这个变量第一次声明的地方,并且将他改名,然后修改在第二次赋值之前的所有引用点,并且在第二次赋值处进行重新声明:

double GetTotalCost()
{
    double result = 0;

    double mealMoney = _chickMoney + _chipMoney;

    result += mealMoney ;

    double money = _cocoaMoney + _coffeeMoney;

    result += money;

    return result;
}

现在,新的临时变量只承担原先money的第一个责任。而且我们在原先money变量第二次被赋值处重新声明了money。然后,继续处理money临时变量的第二次赋值。

double GetTotalCost()
{
    double result = 0;

    double mealMoney = _chickMoney + _chipMoney;

    result += mealMoney ;

    double drinkMoney = _cocoaMoney + _coffeeMoney;

    result += drinkMoney ;

    return result;
}

可以看到,我们完成了变量的重构之后,函数对于临时变量之前的money的困惑已经没有了,整体因为变量名字的本身使得逻辑更加清晰。

如果在这里你的代码还是比较复杂的话,可以尽情使用其他的重构手法。

 小结

这个重构手法的重点在于:临时变量不是用于循环变量和结果收集,但却被赋值超过两次,那就对它进行分解,使其每次只承担一个责任。

6.7Remove Assignments to Parameters(移除对参数的赋值)

概要

代码对一个参数进行赋值。

以一个临时变量取代该参数的位置。

动机

首先要明确这里“对参数赋值”的意思。如果你把一个名为foo的对象作为参数传给某个函数,那么“对参数赋值”就意味着改变foo,使它引用另一个对象。如果在“被传入对象”身上进行什么操作,那是没问题的。Java只采用按值传递的方式,而C#分为值传递和引用传递,关于C#的值传递和引用传递,请看我的另一篇文章,或者自行百度。

int test(int a)
{
    if (a > 50)
    {
        a = 1;
    }
    return a;
}

这个就违反了这个原则,因为你对传入参数进行重新赋值会让代码阅读者产生歧义,降低了代码的清晰度。他们搞不清甚至看不懂你参数到底代表什么含义,甚至会对你这个参数的稳定性表示担忧。

值类型按值传递的情况下,对参数的任何修改,都不会对调用端造成任何影响。这个重构手法也是针对值类型按值传递的。

范例

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

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

int GetDiscount(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;
}

 小结

如果参数只表示“被传递进来的东西”,那么代码会很清晰。

 

To Be Continued...

发表评论
用户名: 匿名