何时提炼函数 & 用查询取代临时变量

声明:本文来自于:http://justjavac.iteye.com/blog/1407833

何时提炼函数 & 用查询取代临时变量

 

拥有 [ 短函数」( short methods )的对象会活得比较好、比较长。不熟悉面向对象技术的人,常常觉得对象程序中只有无穷无尽的 delegation (委托),根本没有进行任何计算。

   

我们遵循这样一条原则:每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立函数中,并以其用途(而非实现手法)命名 。我们可以对一组或甚至短短一行代码做这件事。哪怕替换后的函数调用动作比函数自身还长,只要函数名称能够解释其用途,我们也该毫不犹豫地那么做。关键不在于函数的长度,而在于函数「做什么」和「如何做」之间的语义距离。

     

如何确定该提炼哪一段代码昵? 一个很好的技巧是:寻找注释。它们通常是指出「代码用途和实现手法间的语义距离」的信号。如果代码前方有一行注释,就是在提醒 你:可以将这段代码替换成一个函数,而且可以在注释的基础上给这个函数命名。就算只有一行代码,如果它需要以注释来说明,那也值得将它提炼到独立函数去。

 

以查询取代临时变量  

Replace Temp with Query 往往是你运用 Extract Method 之前必不可少的一个步骤。局部变量会使代码难以被提炼,所以你应该尽可能把它们替换为查询式。

 

方法步骤:

1 :找出只被赋值一次的临时变量(如果某个临时变量被赋值超过一次,考虑用 split temporary variable 将它分割)

2 :将临时变量声明为 final 。(确保变量只是被赋值一次)

3 :编译。

4 :将对该临时变量赋值的语句等号右侧部分提炼到一个独立函数中。(声明为 private ,确保这个函数不修改任何的对象内容)

5 :在该临时变量身上实施用查询取代临时变量。

   

我们常常使用临时变量保存循环中的累加信息。在这种情况下,整个循环都可以被提为一个独立函数,这也使原本的函数可以少掉几行扰人的循环码。有时候,你可能会用单一循环累加好几个值,就像本书 p.26 的例子那样。这种情况下你应该针对每个累加值重复一遍循环,这样就可以将所有临时变量都替换为查询式( query )。

     

Example

1   原来代码

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

   

首先把临时变量声明为 final ,检查是否只是被赋值一次。

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

 

这样一来,如果有任何问题,编译器就会警告我

   

下面一步步来:

首先把 basePrice 右边的提取到一个函数,然后 if 里面的引用这个变量的点,改为调用这个函数:

 

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

 

Java代码   收藏代码
  1. private   int  basePrice() {   
  2.     return  _quantity * _itemPrice;   
  3. }   

 

 

最后的 return 语句是对于这个变量的最后一个引用点,所以把临时变量移除,然后改为调用方法:

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

     

同理提炼 discountFactor ,最后函数变为:

 

Java代码   收藏代码
  1. double  getPrice() {   
  2.     return  basePrice() * discountFactor();   
  3. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值