【阅读笔记】《重构》 第五六章

news/2024/11/9 9:28:10/

第五章 重构列表

重构的记录格式

  • 建造一个重构词汇表
  • 一个简短概要,解决的问题,应该做的事,展示重构前后示例
  • 动机,为什么要重构
  • 做法,介绍如何进行此一重构
  • 范例,说明重构手法如何运作

寻找引用点

  • 利用文本查找工具,检查是否有其他类声明了正在处理的那个函数

重构手法的成熟度

  • 重构的基本技巧——小步前进、频繁测试

第六章 重新组织函数

Extract Method(提炼函数)

  • 动机:看见一个过长的函数或者一段需要注释才能让人理解用途的代码
  • 做法:
    • 创造一个新函数,并根据这个函数的意图来对它明明
    • 将提炼出的代码从源函数复制到新建的目标函数中
    • 仔细检查提炼出的代码,看看其中是否引用了"作用于限于源函数"的变量
    • 检查被提炼代码段,看看是否有任何局部变量的值被它改变
    • 将被提炼代码段中需要读取的局部变量,当作仓鼠传给目标函数
    • 处理完所有局部变量之后,进行编译
    • 在源函数中,将被提炼代码替换为对目标函数的调用
    • 编译测试

Inline Method(内联函数)

  • 动机:手上有一群组织不合理的函数,可以将它们内联到一个大型函数中,再从中提炼出组织合理的小型函数
  • 做法
    • 检查函数,确定它不具多态性
    • 找出这个函数的所有被调用点
    • 将这个函数的所有被调用点都替换为函数本体
    • 编译测试
    • 删除该函数定义

Inline Temp(内联临时变量)

  • 动机:发现某个临时变量被赋予某个函数调用的返回值。一般来说,这种临时变量不会有任何危害,但该临时变量妨碍了其他的重构手法,就应该将它内联化
  • 做法:
    • 检查给临时变量赋值的语句,确保等号右边的表达式没有副作用
    • 如果临时变量并未被声明为final,那就将它声明为final,然后编译
    • 找到该临时变量的所有引用点,将它们替换为"临时变量复制"的表达式
    • 每次修改后,编译并测试
    • 修改完所有引用点之后,删除该临时变量的声明和赋值局域
    • 编译测试

Replace Temp with Query(以查询取代临时变量)

  • 动机:临时变量的问题在于它使暂时的,且只能在所属函数内使用。由于临时变量只在所属函数内可见,所以它们会驱使你写出更长的函数
  • 做法:
    • 找出只被赋值一次的临时变量
    • 将该临时变量声明为final
    • 编译
    • 将"对该临时变量赋值"
    • 编译测试
    • 在该临时变量身上实施Inline Temp

Introduce Explaining Variable(引入解释性变量)

  • 动机:表达式有可能非常复杂而难以阅读
  • 做法:
    • 声明一个final临时变量,将待分解之复杂表达式中的一部分动作的运算结果赋值给它
    • 将表达式中的"运算结果"这一部分,替换为上述临时变量
    • 编译测试
    • 重复上述过程,处理表达式的其他部分

Split Temporary Variable(分解临时变量)

  • 动机:临时变量有各种不同用途,部分变量会很自然地导致临时变量被多次赋值
  • 做法:
    • 在待分解临时变量的声明及其第一次被赋值处,修改其名称
    • 将新的临时变量声明为final
    • 以该临时变量的第二次赋值动作为界,修改此前对该临时变量的所有引用点,让它们引用新的临时变量
    • 在第二次赋值处,重新声明原先那个临时变量
    • 编译测试
    • 逐次重复上述过程,每次都在声明处对临时变量改名,并修改下次赋值之前的引用点

Remove Assignments to Parameters(移除对参数的赋值)

  • 动机:混用了按值传递和按引用传递这两种参数传递方式
  • 做法:
    • 建立一个临时变量,把待处理的参数值赋予它
    • 以"对参数的赋值"为界,将其后所有对此参数的引用点,全部替换为"对此临时变量的引用"
    • 修改赋值语句,使其改为对新建的临时变量赋值
    • 编译测试

Replace Method with Method Object(以函数对象取代函数)

  • 动机:发现根本无法拆解一个需要拆解的函数,可以将所有局部变量都变成函数对象的字段,将原本的大型函数拆解变短
  • 做法:
    • 建立一个新类,根据待处理函数用途进行命名
    • 在新类中建立一个final字段,用以保存原先大型函数所在的对象
    • 在新类中建议一个构造函数,接受源对象及原函数的所有参数作为参数
    • 在新类中建立一个compute()函数
    • 将原函数的代码复制到compute()函数中
    • 编译
    • 将旧函数的函数本体替换掉

Substitute Algorithm(替换算法)

  • 动机:如果发现做一件事可以有更清晰的方式,就应该以较清晰的方式取代复杂的方式
  • 做法:
    • 准备好另一个(替换用)算法,让它通过编译
    • 针对现有测试,执行上述的新算法。如果结果与原本结果相同,重构结束
    • 如果测试结果不同于原先,在测试和调试过程中,以旧算法为比较参照标准

http://www.ppmy.cn/news/18416.html

相关文章

vs code中的platformIO插件,完成Arduino的程序编写,导入,安装开发板管理库

准备工作 vs code已经安装好,扩展插件plateformIO也安装好。(下图是platformIO安装方式) platformIO界面功能介绍和简单使用 新建Arduino项目 选择正确的开发板型号,和自己习惯的编译框架。打开后有一个.ini的配置文件&#x…

MySQL详细教程,2023年硬核学习路线

文章目录前言1. 数据库的相关概念1.1 数据1.2 数据库1.3 数据库管理系统1.4 数据库系统1.5 SQL2. MySQL数据库2.1 MySQL安装2.2 MySQL配置2.2.1 添加环境变量2.2.2 新建配置文件2.2.3 初始化MySQL2.2.4 注册MySQL服务2.2.5 启动MySQL服务2.3 MySQL登录和退出2.4 MySQL卸载2.5 M…

【DX-BT24蓝牙模块连接Arduino与手机透传教程】

【DX-BT24蓝牙模块连接Arduino与手机透传教程】1. 前言2. 接线3. 程序设计详解4. 演示效果5. 小结1. 前言 大夏龙雀科技DX-BT24&BT24-S&BT24-PA蓝牙模块,拥有5.1蓝牙协议,模块内置标准串口协议。前期设置蓝牙名称为VOR,采用默认波特率9600,详细…

SpringCloud项目日志接入ELK实战

文章目录写作背景ELK实战前置环境准备项目里集成Logstash进入Kibana查看日志写作背景 前面我对SpringCloud Netflix相关的组件,Eureka、Ribbon、OpenFeign、Hystrix和Zuul都进行了复习,后面随着代码越写越多就想着,要不就慢慢完善这个项目代…

基于Spring Boot和Spring Cloud实现微服务架构

首先,最想说的是,当你要学习一套最新的技术时,官网的英文文档是学习的最佳渠道。因为网上流传的多数资料是官网翻译而来,很多描述的重点也都偏向于作者自身碰到的问题,这样就很容易让你理解和操作出现偏差,…

Java_Git:2. 使用git管理文件版本

目录 1 创建版本库 1.1 使用GitBash 1.2 使用TortoiseGit 2 添加文件 2.1 添加文件过程 2.2 工作区和暂存区 3 修改文件 3.1 提交修改 3.2 查看修改历史 3.3 差异比较 3.4 还原修改 4 删除文件 5 案例:将java工程提交到版本库 5.1 复制文件到工作目录 …

【GD32F427开发板试用】工业级串口OTA实现----移植韦东山老师BootLoader项目

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:足球之路 一、综述 一款完善的工业产品往往需要支持在线更新程序的需求,业界最近火热的叫法叫做“OTA”。这篇文章记录我利用技术…

maven基础

一、Maven基础 为什么要学习Maven? Maven作为依赖管理工具,能够管理大规模的jarjarjar包,使用MavenMavenMaven后,依赖对应的JarJarJar包,能够自动下载、方便、快捷切规范。Maven作为构建管理工具,当我们使…