`
liuzongan
  • 浏览: 93201 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

重构之临时变量(Replace Temp with Query)

阅读更多

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

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

java 代码
  1. double  basePrice=_quantity * _itemPrice;
  2. if(basePrice>1000){
  3.      return basePrice * 0.95;
  4. else
  5.      return basePrice * 0.38;
  6. }
  7. ......

 

提炼后:

java 代码
  1. if (basePrice()>1000){
        return basePrice() * 0.95
  2. else
  3.     return basePrice() * 0.38
  4. }
  5. ......
  6. double basePrice(){
  7.     return _quantity * _itemPrice;
    }

动机:
临时变量的问题在于:它们是暂时的,而且只能在所属函数内使用,由于临时变量只有在所属内才可见,所以它们会驱使你写出更长的函数,因为只有这样你才能访问到想要访问的临时变量,如果把临时变量替换为一个查询式(query method),那么同一个CLASS中的所有函数都将获得这份信息。这将带给你极大帮助,使你能够为这个CLASS编写更清晰的代码。

这个重构手法较为直率的情况就是:临时变量只被赋值一次,或者赋值给临时变量的表达式不受其他条件影响,其他情况比较情况棘手,但也有可能发生,你可能需要先运用Split Temporary Variable 或Separate Query from Modifier 使情况变得简单一些。如果你想替换的临时变量是用来收集结果的(例如循环中的累加值),你就需要将某些程序的逻辑(例如循环)拷贝到查询式(query method)去。


作法:

  • 找出只被赋值一次的临时变量
  • 将临时变量声明为 final
  • 编译(这可确保临时变量的确只被赋值一次)
  • 将对该临时变量赋值之语句的等号右侧部分提炼到一个独立函数中。详细步骤:首先将函数声明为private,之后你可能会发现有更多CLASS需要使用它,彼时你可轻易放松对它的保护。确保提炼出来的函数无任何连带影响,就对它进行Separate Query from Modifier
  • 编译,测试

 范例:
首先,我从一个简单函数开始:

java 代码
  1. double  getPrice()
  2. {   
  3.      int basePrice=_quantity+_itemPrice;   
  4.      double discountFactor;   
  5.      if(basePrice>1000)   
  6.         discountFactor=0.95;   
  7.      else  
  8.         discountFactor=0.98;   
  9.      return  basePrice = discountFactor;   
  10.    
  11. }  

 我希望将这个两个变量都替换掉,当然,每次一个。

尽管这里的代码十分清楚,我还是先把临时变量声明为final,检查它们是否的确只被赋值一次:

java 代码
  1. double getPrice()   
  2. {   
  3.       final int basePrice = _quantity * _itemPrice;   
  4.       final double discountFactor;   
  5.       if(basePrice>1000)   
  6.          discountFactor=0.95;   
  7.       else  
  8.          discountFactory=0.98;   
  9.       return basePrice * discountFactor;   
  10. }  

这么一来,如果有任何问题,编译器就会警告我,之所以先做这件事,因为如果临时变量不只被赋值一次,不该进行这项重构了,接下来我开始替换临时变量了,每次一个,首先我把赋值动作的右侧表达式提炼出来。

java 代码
  1. double getPrice()   
  2. {   
  3.       final int basePrice = basePrice();   
  4.       final double discountFactor;   
  5.       if(basePrice >1000)   
  6.          discountFactor =0.95;   
  7.       else  
  8.          discountFactor =0.98;   
  9.       return basePrice * discountFactor;   
  10. }   
  11. private int basePrice()   
  12. {   
  13.       return _quantity * _itemPrice;   
  14. }   
  15.     

再把临时变量的引用点替换掉:

java 代码
  1. double getPrice()   
  2. {   
  3.     final int basePrice = basePrice();   
  4.     final double discountFactor;   
  5.     if ( basePrice()>1000 )   
  6.        discountFactor = 0.95;   
  7.     else  
  8.        discountFactor = 0.98;   
  9.    return basePrice() * discountFactor;   
  10. }  

下一步:

java 代码
  1. double getPrice()      
  2. {      
  3.     final double discountFactor;      
  4.     if ( basePrice()>1000 )      
  5.        discountFactor = 0.95;      
  6.     else     
  7.        discountFactor = 0.98;      
  8.    return basePrice() * discountFactor;      
  9. }    

下一步(仔细观察代码)

java 代码
  1. double getPrice()      
  2. {      
  3.    return basePrice() * discountFactor();      
  4. }     
  5.   
  6. private double discountFactor()   
  7. {   
  8.     if ( basePrice()>1000 )      
  9.        return  0.95;      
  10.     else     
  11.        return  0.98;      
  12. }   
  13.   
  14. private int basePrice()   
  15. {   
  16.     return _quantity * _itemPrice;   
  17. }  

是多么简单啊(代码有错请指点)

 

分享到:
评论
2 楼 element8325 2007-10-16  
貌似连代码都没改,用自己的理解写一段会比较好
1 楼 eivenchan 2007-10-16  
似乎是《重构》一书中的内容?

相关推荐

    编码中的21种代码坏味道

    如果你已经使用了 Extract Method(110)、Replace Temp with Query(120)和 Introduce Parameter Object(295)等方法,但仍然有太多临时变量和参数,那就可以使用 Replace Method with Method Object(135)来将...

    重构-改善既有代码的设计(中文版)

     *Replace Temp with Query 用查询方法代替临时变量   Introduce Explaining Variable 引入解释性变量   Split Temporary Variable 分离临时变量   *Remove Assignments to Parameters 去除参数赋值   ...

    重构-改善既有代码的设计+中文版

     *Replace Temp with Query 用查询方法代替临时变量   Introduce Explaining Variable 引入解释性变量   Split Temporary Variable 分离临时变量   *Remove Assignments to Parameters 去除参数赋值   ...

    重构-改善既有代码的设计

    6.4 Replace Temp with Query(以查询取代临时变量) 120 6.5 Introduce Explaining Variable(引入解释性变量) 124 6.6 Split Temporary Variable(分解临时变量) 128 6.7 Remove Assignments to ...

    重构 改善既有代码的设计

     *Replace Temp with Query 用查询方法代替临时变量   Introduce Explaining Variable 引入解释性变量   Split Temporary Variable 分离临时变量   *Remove Assignments to Parameters 去除参数赋值   ...

    重构——改善既有代码的设计

     *Replace Temp with Query 用查询方法代替临时变量   Introduce Explaining Variable 引入解释性变量   Split Temporary Variable 分离临时变量   *Remove Assignments to Parameters 去除参数赋值   ...

    重构,改善既有代码的设计

     *Replace Temp with Query 用查询方法代替临时变量   Introduce Explaining Variable 引入解释性变量   Split Temporary Variable 分离临时变量   *Remove Assignments to Parameters 去除参数赋值   ...

    重构:改善既有代码的设计.[美]Martin Fowler.epub【文字版手机格式】

    6.4 Replace Temp with Query(以查询取代临时变量) 6.5 Introduce Explaining Variable(引入解释性变量) 6.6 Split Temporary Variable(分解临时变量) 6.7 Remove Assignments to Parameters(移除对参数的赋值) ...

    重构-改善既有代码的设计 中文版

    6.4 Replace Temp With Query(以查询取代临时变量) 6.5 Introduce Explaining Variable(引入解释性变量) 6.6 Split Temporary Variable(剖解临时变量) 6.7 Remove Assignments to Paramete (移除对参数的赋值...

    重构-改善既有代码的设计.rar

    例如,"Replace Temp with Query"(用查询取代临时变量)是常见的重构手法,它鼓励我们直接从对象获取所需的信息,而不是先存储再使用;"Introduce Parameter Object"(引入参数对象)则是将多个参数组合成一个对象...

    重构与模式.pdf

    8. **替换临时变量**(Replace Temp with Query):将临时变量转换为只读属性或方法,减少局部变量的数量,使代码更加简洁。 9. **移除设置器**(Remove Setting Method):如果一个对象的状态变化过于频繁,可以...

    Refactoring Improving the Design of Existing Code.pdf 代码重构

    "Replace Temp with Query"(用查询替换临时变量)则旨在减少临时变量的使用,使代码逻辑更加清晰。这些重构技术都是在不改变程序行为的前提下,逐步改善代码结构。 此外,书中还讨论了何时以及如何进行重构。...

    重构:改善既有代码的设计

    “替换临时变量”(Replace Temp with Query)和“引入解释性变量”(Introduce Explaining Variable)则是处理复杂表达式的有效手段。 ### 总结 《重构:改善既有代码的设计》不仅是一本技术指南,更是一种思维...

    重构:改善既有代码的设计(中文版).

    6.4 ReplaceTempwithQuery(以查询取代临时变量)120 6.5 IntroduceExplainingVariable(引入解释性变量)124 6.6 SplitTemporaryVariable(分解临时变量)128 6.7 RemoveAssignmentstoParameters(移除对参数的赋值...

    重构:改善既有代码的设计(中文高清版)

    6.4 ReplaceTempwithQuery(以查询取代临时变量)120 6.5 IntroduceExplainingVariable(引入解释性变量)124 6.6 SplitTemporaryVariable(分解临时变量)128 6.7 RemoveAssignmentstoParameters(移除对参数的赋值...

    重构_改善既有代码的设计

    - **替换临时变量**(Replace Temp with Query):将一个方法内的临时变量替换为直接调用的计算表达式或查询方法。 - **简化条件表达式**(Simplify Conditional Expressions):通过逻辑重组或引入新的方法来简化...

    经典书籍《重构》《Refactoring: Improving the Design of Existing Code》

    - **替换临时变量**(Replace Temp with Query):将临时变量替换为一个方法,以提高代码的清晰度和可读性。 - **移动字段**(Move Field):将一个类中的字段移动到另一个类中,以改善类之间的耦合性。 #### 重构...

Global site tag (gtag.js) - Google Analytics