《重构改善既有代码的设计》之重构列表--重新组织函数(一)

2023-12-16 14:58

本文主要是介绍《重构改善既有代码的设计》之重构列表--重新组织函数(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Extract Method(提炼函数)

你有一段代码可以被组织在一起并独立出来。

将这段代码放进一个独立函数中,并让函数名称解释该函数的用途。

Void printOwing(double amount){

printBanner();

//print details

System.out.println("name:" + _name);

System.out.println("amount:" + amount);

}

提炼后:

Void printOwing(double amount){

printBanner();

printDetails();

}

 

void printDetails(){

//print details

System.out.println("name:" + _name);

System.out.println("amount:" + amount);

}

动机

Extract Method是最常用的重构手法之一。当看到一个过长的函数或者一段需要注释才能让人理解用途的代码,就会将这段代码放到一个独立函数中。

有几个原因造成我喜欢简短而命名良好的函数。首先,如果每个函数的粒度都很小,那么函数被复用的机会就更大;其次,这会使高层函数读起来就像一系列注释;再次,如果函数都是细粒度,那么函数的覆写也会更容易些。

做法

1、创造一个新函数,根据这个函数的意图来对它命名(以它“做什么”来命名,而不是以它“怎样做”命名)。

2、将提炼出来的代码从源函数中复制到新建的目标函数中。

3、仔细检查提炼出的代码,看看其中是否引用了“作用域限于源函数”的变量(包括局部变量和临时变量)。

4、检查是否有“仅用于被提炼代码段”的临时变量。如果有,在目标函数中将它们声明为临时变量。

5、检查被提炼代码段,看看是否有任何局部变量的值被它改变。如果一个临时变量值被修改了,看看是否可以将被提炼代码段处理为一个查询,并将结果赋值给相关变量。如果很难这样做,或如果被修改的变量不止一个,你就不能仅仅将这段代码原封不动地提炼处理。你可能需要先运用Split Temporary Variable,然后再尝试提炼。也可以使用Replace Temp with Query将临时变量消灭掉。

6、将被提炼代码段中需要读取的局部变量,当做参数传给目标函数。

7、处理完所有局部变量之后,进行编译。

8、在源函数中,将被提炼代码段替换为对目标函数的调用。

9、编译、测试。

二、Inline Method(内联函数)

    一个函数的本体与名称同样清晰易懂。

在函数调用点插入函数本体,然后移除该函数。 

int Rating(){

    Return(moreThanFiveLateDliveries())?2:1;

}

Boolean moreThanFiveLateDeliveries(){

Return _numberOfLateDeliveries > 5;

}

转换后:

int Rating(){

    Return (_numberOfLateDeliveries > 5)?2:1;

}

动机

本书经常以简短的函数表现动作意图,这样会使代码更清晰易懂。但有时候你会遇到某些函数,其内部代码函数名称一样清晰易读。也可能你重构了函数,使得其内容和其名称变得同样清晰。果真如此,你就应该去掉这个函数,直接使用其中的代码。间接性可能带来帮助,但非必要的间接性总是让人不舒服。

另一种需要使用Inline Method 的情况是:你手上有一群组织不甚合理的函数。你可以将它们都内联到一个大型函数中,再从中提炼出组织合理的小型函数。

做法

1、检查函数,确定它不具多态性。

?  如果子类继承了这个函数,就不要将此函数内联,因为子类无法覆写一个根本不存在的函数。

2、找出这个函数的所有引用点。

3、将这个函数的所有被调用点都替换为函数本体。

4、编译、测试。

5、删除该函数的定义。

三、Inline Temp(内联临时变量)   

你有一个临时变量,只被一个简单表达式赋值一次,而它妨碍了其他重构手法。

将所有对该变量的引用动作,替换为对它赋值的那个表达式本身。

Double basePrice = anOrder.basePrices();

Return (basePrice > 1000);

转换后:

Return ( anOrder.basePrices() > 1000);

动机

Inline Temp多半是作为Replace Temp with Query的一部分使用,所以真正的动机出现在后者那儿。唯一单独使用Inline Temp的情况是:你发现某个临时变量被赋予某个函数调用的返回值。一般来说,这样的临时变量不会有任何危害,可以放心地把它留在那儿。但如果这个临时变量妨碍了其他重构手法,例如Extract Method,你就应该将它内联化。

做法

1、检查给临时变量赋值的语句,确保等号右边表达式没有副作用。

2、如果这个临时变量并未声明为final ,那么就将它声明为final ,然后编译。(这可以检查该临时变量是否真的只被赋值一次)

3、找到该临时变量的所有引用点,将它们替换为“为临时变量赋值”的表达式。

4、每次修改后,编译并测试。

5、修改完所有引用点后,删除该临时变量的声明和赋值语句。

6、编译、测试。

这篇关于《重构改善既有代码的设计》之重构列表--重新组织函数(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500874

相关文章

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

Python get()函数用法案例详解

《Pythonget()函数用法案例详解》在Python中,get()是字典(dict)类型的内置方法,用于安全地获取字典中指定键对应的值,它的核心作用是避免因访问不存在的键而引发KeyError错... 目录简介基本语法一、用法二、案例:安全访问未知键三、案例:配置参数默认值简介python是一种高级编

python 常见数学公式函数使用详解(最新推荐)

《python常见数学公式函数使用详解(最新推荐)》文章介绍了Python的数学计算工具,涵盖内置函数、math/cmath标准库及numpy/scipy/sympy第三方库,支持从基础算术到复杂数... 目录python 数学公式与函数大全1. 基本数学运算1.1 算术运算1.2 分数与小数2. 数学函数

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码