『重构--改善既有代码的设计』读书笔记----Introduce Explaning Variable

有时候你会遇到一系列复杂的表达式连续运算的时候,这个时候你可能根本招架不住如此长或者是如此复杂的长函数。这个时候你可以通过引用临时变量来储存他们的结果,将这些长函数的结果分成一个个临时变量来让函数清晰化。但在这里,我的想法与作者的想法是一样的,我会更倾向于去用Extract Method去将复杂函数弄清晰,而尽量不去Introduce Explaning Vaiable,因为Extract Method优点很多,除了不增加临时变量增加函数长度之外,他的生命周期也比临时变量来的长,他可以让类中的所有成员都可以用到。除非临时变量让Extract Method很难进行,我才会真正去考虑采用临时变量来解决。

做法一般是用const声明一个临时变量来存储表达式的值,然后对引用表达式结果的地方进行替换。下面看下具体例子

double price()
{
    return m_quantity * m_itemPrice - qMax(0, m_quantity - 500) * m_itemPrice * 0.05
        + qMin(m_quantity * m_itemPrice * 0.1, 100.0);
}

对于这种长函数我们很难招架,可以进行Introduce Explaning Variable,将m_quanity * m_itemPrice进行提炼,得到如下

double price()
{
    const double basePrice = m_quantity * m_itemPrice;
    return basePrice - qMax(0, m_quantity - 500) * m_itemPrice * 0.05
        + qMin(basePrice * m_itemPrice * 0.1, 100.0);
}

我们将basePrice以const double类型声明并且初始化,将所有引用这个表达式结果的地方进行替换,我们可以看到,算法的逻辑清晰了一点。

在这里为了验证我的观点,我们来用下Extract Method来进行重构,看看结果会有何不同。

double price()
{
    return basePrice() - qMax(0, m_quantity - 500) * m_itemPrice * 0.05
        + qMin(basePrice() * 0.1, 100.0);
}

double basePrice()
{
    return m_quantity * m_itemPrice;
}

看了运用Extract Method手法的结果,对比之后我们可以发现有前者有以下几个优点:

【1】也是最明显的,Extract Method之后的结果要比Introduce Explaning Variable清晰并且简短的多,其实这也是肯定的,因为后者会引入临时性变量,更加会增加函数的长度。

【2】对于basePrice的提炼,对于price()这个函数来说,Introduce Explaning Variable提炼的临时变量只能在本函数中使用,而Extract Method确可以在类中所有地方都可以使用。

综合来看,Extract Method确实要比Introduce Explaning Variable好用的多,而且我们可以发现,工作量来说两者几乎没什么差别。那么同学会问,那这个重构手法什么时候才会去用?还是有的,就是当Extract Method无法顺利展开的时候,比如临时变量很多不能提炼,这个时候引入临时性变量就容易的多。而且等到代码逻辑清晰之后,你再运用Replace Temp with Query也可以很轻松的去除那些临时性变量。如果你最终要使用Replace Method with Method Object,那么这个手法也就对你提炼提供了价值。

时间: 2024-10-29 16:58:12

『重构--改善既有代码的设计』读书笔记----Introduce Explaning Variable的相关文章

『重构--改善既有代码的设计』读书笔记----Split Temporary Variable

继续开始我们重构手法的系列,今天介绍的是Split Temporary Variable---分解临时变量. 在我们平常写的程序中肯定有某些临时变量被赋予了超过一个的责任.如果他们不是那种收集结果(temp = temp + QString("abc"))或者循环变量(i = i + 1),然而他们却被赋值了多于一次.那么我们肯定说,这个变量被赋予了超过一个的责任,别看这是个小小问题,但这会阻扰我们阅读者的判断,我们会去揣测,这个变量到底是用来干嘛的.从而影响我们看清程序正常的思路.

『重构--改善既有代码的设计』读书笔记----Introduce Local Extension

同Introduce Foreign Method一样,很多时候你不能修改编辑原始类,你需要为这些服务类增加一些额外的函数,但你没有这个权限或者入口.如果你只需要一个或者两个外加函数那么你可以放心的使用Introduce Foregin Method,但是如果你发现此时有很多外加函数需要在客户类代码中中添加,你就要小心了,因为你这么做你就会让客户类变得过分复杂,责任就会过分多,你会破坏客户类的单一职责性.这个时候你就可以建立一个新类,让他来包含这些你之前所添加的额外函数,让这个扩展类成为源类的子

『重构--改善既有代码的设计』读书笔记----Extract Method

在编程中,比较忌讳的一件事情就是长函数.因为长函数代表了你这段代码不能很好的复用以及内部可能出现很多别的地方的重复代码,而且这段长函数内部的处理逻辑你也不能很好的看清楚.因此,今天重构第一个手法就是处理长函数--Extract Method,抽取成一个独立的小函数. 我个人来说也很喜欢短小函数,因为他们代表了高强度的复用与灵活性.对于短小函数来说最最关键的就是短小函数的命名,其实你就是给了这些短小函数自我解释的机会,所以你如果给这些短小函数起一个接近其语义的名字,那当你读起长函数来说,就像是阅读

『重构--改善既有代码的设计』读书笔记----Change Value to Reference

有时候你会认为某个对象应该是去全局唯一的,这就是引用(Reference)的概念.它代表当你在某个地点对他进行修改之后,那么所有共享他的对象都应该在再次访问他的时候得到相应的修改.而不会像值对象(Value)一样,不可修改.举个例子,你认识小明,我也认识小明,小明忽然把头发都踢了,这个时候你认识的小明和我认识的小明都是同一个人,都是光头,这个小明就是世界的唯一实例,然而,你有100块钱,我有50块钱,我把50块钱花到只剩20,你手里的100块钱并不会因为我的50块钱改变而改变,不会相应的修改,这

『重构--改善既有代码的设计』读书笔记----Replace Method with Method Object

有时候,当你遇到一个大型函数,里面的临时变量和参数多的让你觉得根本无法进行Extract Method.重构中也大力的推荐短小函数的好处,它所带来的解释性,复用性让你收益无穷.但如果你遇到上种情况,你可能会天真的以为我只要适当的进行Replace Temp with Query,就可以把这种现象给化解.但情况往往事与愿违,不能达到你所理想的高度.这个时候你需要用到重构中的杀手锏--Replace Method with Method Object,这个手法出自Kent Beck [Beck].

『重构--改善既有代码的设计』读书笔记----Move Method

明确函数所在类的位置是很重要的.这样可以避免你的类与别的类有太多耦合.也会让你的类的内聚性变得更加牢固,让你的整个系统变得更加整洁.简单来说,如果在你的程序中,某个类的函数在使用的过程中,更多的是在和别的类进行交互,调用后者或者被后者调用,那么你就要注意了,你要去判断这个类是否真正适合他原来所在的类. 简单来说,这套手法就是在该函数最常引用的新类中建立一个有着类似行为的新函数,让旧函数变成一个单纯的委托函数或者完全删掉. Move Method是重构理论的支柱.如果一个类的责任太多,或者一个类和

『重构--改善既有代码的设计』读书笔记----代码坏味道【3】

星期六了,适当出去放松了下,回来继续我们重构的话题.今天是坏味道[3]了,很多朋友跟我私信,叫我把坏味道出完,再出手法.其实这是有道理的,很多时候,"发现"远比"怎么做"重要的多.就拿设计模式来讲,GoF里面的设计模式相信有很多人都了解过.具体的设计模式应该怎么实现啊相信有很多人都背的滚瓜烂熟,但问题的难点往往在于你应该什么时候用这个设计模式.重构也一样,手法步骤都是死的,关键在于应该发现什么时候应该重构.所以,我还是决定继续出坏味道,把坏味道全部出完我们再去学手法

『重构--改善既有代码的设计』读书笔记----Extract Class

在面向对象中,对于类这个概念我们应该有一个清晰的责任认识,就是每个类应该只有一个变化点,每个类的变化应该只受到单一的因素,即每个类应该只有一个明确的责任.当然了,说时容易做时难,很多人可能都会和我一样,一开始建立类的时候信心满满,牢记SRP原则,但随着开发进度的不断进行,很有可能你会给你原本设计好的类增加新字段或者增加新函数,对于少量的增加你可能会因为麻烦,考虑不去单独做一个新类来分解.久而久之,你这个类会变得越来越臃肿,所掌管的责任也会越来越多.这样的类往往还有大量的数据和函数,往往太大而不易

『重构--改善既有代码的设计』读书笔记----Replace Data Value with Object

当你在一个类中使用字段的时候,发现这个字段必须要和其他数据或者行为一起使用才有意义.你就应该考虑把这个数据项改成对象.在开发初期,我们对于新类中的字段往往会采取简单的基本类型形式来保存,但随着我们开发进度的增加,这些简单的数据项就不再那么简单了.比如一开始你会使用一个字符串来表示一串电话号码,但是随后你会发现,这个电话号码已经变的不再纯粹,它可能还需要“格式化”,“抽取取号”等特殊行为.一开始你可能会不以为意,觉得这个数据项就这么一两个,不会对你造成影响.但重复代码(Duplicate Code