zoukankan      html  css  js  c++  java
  • 重构手法之重新组织函数【2】


     返回总目录


    4 Replace Temp with Query(以查询取代临时变量)

    概要

    你的程序以一个临时变量保存某一表达式的运算结果。

    将这个表达式提炼到一个独立函数中。将这个临时变量的所有引用点替换为对函数的调用。此后,新函数就可以被其他函数使用。

    动机

    临时变量的问题在于:只在当前函数可见。如果你在同类的别的地方访问这个变量,你就必须重新写表达式来获取这个变量,这样的话你就会在不经意间让你的函数变得复杂起来。如果将临时变量替换为一个查询,那么同类中所有函数都可以获得这份信息。

    所以如果你想要使用Extract Method,那么Replace Temp with Query是必不可少的一个步骤。而我们前面介绍的Inline Temp其实是这个手法的一部分,两者的区别在于Inline Temp已经有了表达式自身,只需要做简单的替换就可以,需要用表达式本身把临时变量给去掉。而Replace Temp with Query更加全面,里面包含了提炼表达式到函数本身,然后替换引用点(Inline Temp)。如果你把所有的临时变量都替换为一个查询,你的类的结构和逻辑将非常清晰,这样将更加有利于你的重构和进行优化。

    范例

    假设有以下简单函数:

    double GetPrice()
    {
       int basePrice = _quantity * _itemPrice;
       double discountFactor;
       if (basePrice > 1000)
       {
           discountFactor = 0.95;
       }
       else
       {
           discountFactor = 0.98;
       }
       return basePrice * discountFactor;
    }    

    我们现在将basePrice 和discountFactor这两个临时变量都替换掉。

    先来替换basePrice,将basePrice右侧表达式提炼出来,然后使用Inline Temp将basePrice的所有引用点都替换掉,并且把basePrice临时变量的声明去掉。

    现在代码变成这样:

    double GetPrice()
    {
       double discountFactor;
       if (GetBasePrice() > 1000)
       {
          discountFactor = 0.95;
       }
       else
       {
          discountFactor = 0.98;
       }
       return GetBasePrice() * discountFactor;
     }
    
    private int GetBasePrice()
    {
       return _quantity * _itemPrice;
    }

    再以类似的方法提炼出GetDiscountFactor();

    private double GetDiscountFactor()
    {
       if (GetBasePrice() > 1000)
       {
           return 0.95;
       }
       return 0.98;
    }

    最终代码是这样的。

    double GetPrice()
    {
       return GetBasePrice() * GetDiscountFactor();
    }
    
    private double GetDiscountFactor()
    {
        if (GetBasePrice() > 1000)
        {
            return 0.95;
        }
       return 0.98;
    }
    
    private int GetBasePrice()
    {
       return _quantity * _itemPrice;
    }

    可以明显的看到,这个重构手法对于函数本身来说,提高了清晰度,也让我们进行后期重构能够更加便捷。

    小结

    我们常常在循环中用临时变量保存累加信息。如果是这种情况的话,我们可以将整个循环都提炼出来。如果在循环中要累加好几个值,那么就应该针对每个累加值重复一遍循环。这样,就可以很方便的将所有临时变量都替换为查询。

    当然,这样一来,我们可能担心性能问题。本来我定义一个临时变量只需要查询一次,现在我每次都要去做查询。这个我们完全不必担心。重构的目的是让程序更加清晰,有了更加清晰的程序之后再具体做优化也不迟,况且根据二八原则,仅仅这条查询语句倘若你系统真的出现了性能问题也不大可能,如果实在是因为这条语句,你也可以把变量再放回去。

    To Be Continued...

  • 相关阅读:
    用户 NT AUTHORITY\NETWORK SERVICE 登录失败解决方法
    [转]改变ASP.NET 2.0中的Membership的密码要求
    WINDOWS2003自动开关机的实现
    解决ASP.NET 的进程帐户没有访问 IIS的权限[转]
    byron的一首好诗
    推荐一个好用的日期控件
    程序员喝酒文化
    快速清除Word文档多余空行
    net2.0"服务器应用程序不可用"问题解决[转]
    GridView的第一列是ButtonField,字段名是"删除",想一点之后弹出确认框,否则返回.应该如何写?
  • 原文地址:https://www.cnblogs.com/liuyoung/p/7840722.html
Copyright © 2011-2022 走看看