拥有[短函数」(short methods)的对象会活得比较好、比较长。不熟悉面向对象技术的人,常常觉得对象程序中只有无穷无尽的delegation(委托),根本没有进行任何计算。
我们遵循这样一条原则:每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立函数中,并以其用途(而非实现手法)命名。我们可以对一组或甚至短短一行代码做这件事。哪怕替换后的函数调用动作比函数自身还长,只要函数名称能够解释其用途,我们也该毫不犹豫地那么做。关键不在于函数的长度,而在于函数「做什么」和「如何做」之间的语义距离。
如何确定该提炼哪一段代码昵? 一个很好的技巧是:寻找注释。它们通常是指出「代码用途和实现手法间的语义距离」的信号。如果代码前方有一行注释,就是在提醒你:可以将这段代码替换成一个函数,而且可以在注释的基础上给这个函数命名。就算只有一行代码,如果它需要以注释来说明,那也值得将它提炼到独立函数去。
以查询取代临时变量:
Replace Temp with Query往往是你运用Extract Method 之前必不可少的一个步骤。局部变量会使代码难以被提炼,所以你应该尽可能把它们替换为查询式。
方法步骤:
1:找出只被赋值一次的临时变量(如果某个临时变量被赋值超过一次,考虑用split temporary variable将它分割)
2:将临时变量声明为final。(确保变量只是被赋值一次)
3:编译。
4:将对该临时变量赋值的语句等号右侧部分提炼到一个独立函数中。(声明为private,确保这个函数不修改任何的对象内容)
5:在该临时变量身上实施用查询取代临时变量。
我们常常使用临时变量保存循环中的累加信息。在这种情况下,整个循环都可以被提为一个独立函数,这也使原本的函数可以少掉几行扰人的循环码。有时候,你可能会用单一循环累加好几个值,就像本书p.26的例子那样。这种情况下你应该针对每个累加值重复一遍循环,这样就可以将所有临时变量都替换为查询式(query)。
Example:
1: 原来代码
double getPrice() {
int basePrice = _quantity * _itemPrice;
double discountFactor;
if (basePrice > 1000) {
discountFactor = 0.95;
} else {
discountFactor = 0.98;
}
return basePrice * discountFactor;
}
首先把临时变量声明为final,检查是否只是被赋值一次。
double getPrice() {
final int basePrice = _quantity * _itemPrice;
final double discountFactor;
if (basePrice > 1000) {
discountFactor = 0.95;
} else {
discountFactor = 0.98;
}
return basePrice * discountFactor;
}
这样一来,如果有任何问题,编译器就会警告我
下面一步步来:
首先把basePrice右边的提取到一个函数,然后if里面的引用这个变量的点,改为调用这个函数:
double getPrice() {
final int basePrice = basePrice();
final double discountFactor;
if (basePrice() > 1000) {
discountFactor = 0.95;
} else {
discountFactor = 0.98;
}
return basePrice * discountFactor;
}
private int basePrice() {
return _quantity * _itemPrice;
}
最后的return语句是对于这个变量的最后一个引用点,所以把临时变量移除,然后改为调用方法:
double getPrice() {
final double discountFactor;
if (basePrice() > 1000) {
discountFactor = 0.95;
} else {
discountFactor = 0.98;
}
return basePrice() * discountFactor;
}
同理提炼discountFactor,最后函数变为:
double getPrice() {
return basePrice() * discountFactor();
}
非常简练了了!!
分享到:
相关推荐
6.1 ExtractMethod(提炼函数)110 6.2 InlineMethod(内联函数)117 6.3 InlineTemp(内联临时变量)119 6.4 ReplaceTempwithQuery(以查询取代临时变量)120 6.5 IntroduceExplainingVariable(引入解释...
book-refactoring2-code 存储 《重构: 改善既有代码的设计第二版》的一些示例代码 单元测试 使用 作为我们单元测试套件 ...play 变量可以由 performance 变量计算得到, 以查询取代临时变量 内联变量: 使用 pla
6.1 ExtractMethod(提炼函数)110 6.2 InlineMethod(内联函数)117 6.3 InlineTemp(内联临时变量)119 6.4 ReplaceTempwithQuery(以查询取代临时变量)120 6.5 IntroduceExplainingVariable(引入解释性变量)...
6.1 ExtractMethod(提炼函数)110 6.2 InlineMethod(内联函数)117 6.3 InlineTemp(内联临时变量)119 6.4 ReplaceTempwithQuery(以查询取代临时变量)120 6.5 IntroduceExplainingVariable(引入解释性变量)...
6.1 Extract Method(提炼函数) 6.2 Inline Method(将函数内联化) 6.3 Inline Temp(将临时变量内联化) 6.4 Replace Temp With Query(以查询取代临时变量) 6.5 Introduce Explaining Variable(引入解释性变量...
6.1 ExtractMethod(提炼函数)110 6.2 InlineMethod(内联函数)117 6.3 InlineTemp(内联临时变量)119 6.4 ReplaceTempwithQuery(以查询取代临时变量)120 6.5 IntroduceExplainingVariable(引入解释性变量)...
6.1 Extract Method(提炼函数) 110 6.2 Inline Method(内联函数) 117 6.3 Inline Temp(内联临时变量) 119 6.4 Replace Temp with Query(以查询取代临时变量) 120 6.5 Introduce Explaining ...
6.1 ExtractMethod(提炼函数)110 6.2 InlineMethod(内联函数)117 6.3 InlineTemp(内联临时变量)119 6.4 ReplaceTempwithQuery(以查询取代临时变量)120 6.5 IntroduceExplainingVariable(引入解释性变量)...
6.1 Extract Method(提炼函数) 6.2 Inline Method(内联函数) 6.3 Inline Temp(内联临时变量) 6.4 Replace Temp with Query(以查询取代临时变量) 6.5 Introduce Explaining Variable(引入解释性变量) 6.6 Split...
过长参数列表(Long Parameter List)可以通过引入参数对象(Introduce Parameter Object)或者以查询取代参数来解决,减少函数调用时的负担,提高可读性。 全局数据(Global Data)和可变数据(Mutable Data)可能...
C语言的编写需要遵循一定的规则,包括变量声明、函数定义、表达式的使用等。良好的编程习惯有助于提高代码的可读性和维护性。 #### 5. C语言与其它语言的区别 与其他高级语言相比,C语言更接近底层硬件,因此在性能...
1. **提炼函数**:将过长或难以理解的代码段提取成独立的函数,提高代码的可读性。重构前后对比显示,长函数被拆分成多个小函数,每个函数都有明确的职责。 2. **引入解释性变量**:将复杂表达式的结果存储到临时...
- 代码片段使用了iostream.h头文件,这是一个包含标准输入输出流对象和函数的头文件,虽然在现代C++中已被iostream所取代。 - 函数add是一个简单的整数加法函数,该函数接收两个int类型的参数,并返回它们的和。 ...
根据提供的文件信息,以下是从标题、描述、以及部分问题中提炼出的相关IT知识点: ### PHP面试题目及答案 #### 基础题知识点 **1. 表单中GET与POST提交方法的区别** - **GET**:通过URL参数传递信息进行接收。...
7. **考虑用运算符的赋值形式(OP=)取代其单独形式(OP)** - 在许多情况下,使用复合赋值运算符(如 +=, -= 等)可以提高代码的效率和可读性。 8. **考虑变更程序库** - 有时候,更换更高效或更适合当前需求的...
- **以查询取代临时变量**:使用查询函数替换含义明确的变量,增强代码清晰度。 - **以管道取代循环**:利用函数式编程的管道操作符代替循环结构,简化代码流程。 **代码重构的工具** - **IntelliJ IDEA** - **...
可以通过**提取方法**、**组合方法**、**以查询取代临时变量**等方法将其拆分为更小、更专注的函数。 3. **过长参数列**:过多的参数使得函数调用繁琐且易出错。考虑**以方法取代参数**、**引入参数对象**来简化...