《重构 改善既有代码的设计 1》重构原则

重构-改善既有代码的设计 pdf 阅读详情

前言

重构 既有代码的设计,一本经典神书,两年前入手,一年前看了一半,感觉一般般,今天起,再次拜读,希望会有不一样的收获!

/**
* @startTime 2020-12-16 23:22
* @endTime 2020-12-16 23:59
* @startPage 1 
* @endPage 55
* @efficiency 56/1 = 56页/天
* @needDays 412/56 = 7天
* @overDay 2020-12-16 + 7天 = 2020-12-22 
*/

第1章 重构,第一个案例

所谓重构,是在不改变代码外在行为的前提下,对代码做出修改,以改进程序的内部结构。重构是一种千锤百炼形成的有条不紊的程序整理方法,可以最大限度地减少整理过程中引入错误的几率。本质上说,重构就是在代码写好之后改进它的设计。

任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员。

第2章 重构原则

1、何谓重构

对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。

重构的目的是使软件更容易被理解和修改。

越难看出代码所代表的设计意图,就越难保护其中的设计,经常性的重构可以帮助代码保持自己该有的形态。完成同一件事,设计不良的程序往往需要更多的代码,这常常是因为代码在不同的地方使用完全相同的语句做同样的事情。因此改进设计的一个重要方向就是消除重复代码,这个动作的重要性在于方便未来的修改。代码量减少并不会使系统运行更快,因为这对程序运行轨迹几乎没有任何明显影响。然而代码量减少将使未来可能的程序修改动作容易得多。

/**
* @startTime 2020-12-17 22:00
* @endTime 2020-12-17 22:50
* @startPage 56 
* @endPage 64
* @efficiency 64/2 = 32页/天
* @needDays 412/32 = 13天
* @overDay 2020-12-16 + 13天 = 2020-12-29 
*/

2、重构使软件更容易理解

让review的人更容易理解,让下一个接手你代码的人,更容易理解。也许下一个接手你代码的人就是你自己。有的时候,一段代码拿过来,是不是你自己写的,你都确定不了,对吧?

  • 重构的好处
  • 重构帮助找到bug
  • 重构提高编程速度

3、重构的时机

  • 事不过三,三则重构
  • 添加功能时重构
  • 修改错误时重构
  • 复审代码时重构

4、为什么重构有用

  1. 难以阅读的程序,难以修改;
  2. 逻辑重复的程序,难以修改;
  3. 添加新行为时需要修改已有代码的程序,难以修改;
  4. 带复杂条件逻辑的程序,难以修改;

因此,我们希望程序:

  1. 容易阅读;
  2. 所有逻辑都只在唯一地点指定;
  3. 新的改动不会危及现有行为;
  4. 尽可能简单表达条件逻辑;

间接层和重构

间接层的价值:

  1. 允许逻辑共享;
  2. 分开解释意图和实现;
  3. 隔离变化;
  4. 封装条件逻辑;

5、重构的难题

(1)数据库

数据迁移

(2)修改接口

不要过早发布接口,请修改你的代码所有权政策,使重构更顺畅。

(3)难以通过重构手法完成的设计改动

(4)何时不该重构 

/**
* @startTime 2020-12-20 11:50
* @endTime 2020-12-20 15:30
* @startPage 65 
* @endPage 102
* @efficiency 102/5 = 20.4页/天
* @needDays 412/20.4 = 20天
* @overDay 2020-12-16 + 20天 =  2020-01-04
*/

6、重构和设计

很多人都把设计看做软件开发的关键环节,而把编程看做只是机械式的低级劳动。他们认为设计就像画工程图而编码就像施工。

哪怕你完全了解系统,也请实际度量它的性能,不要臆测。臆测会让你学到一些东西,但十有八九你是错的。

7、重构和性能

首先写出可调的软件,然后调整它以获得足够的速度。

三种编写快速软件的方法:

(1)时间预算法

通常用于性能要求极高的实时系统。

分解设计时要做好预算,给每个组件预先分配一定的资源,包括时间和执行轨迹。每个组件决不能超出自己的预算,就算拥有组件之间的调度预配时间的机制也不行。

这种方法高度重视性能,对于心率调节器一类的系统是必须的,因为这样的系统中迟来数据就是错误的。但对一些管理系统来说,如此追求性能就有点过分了。

(2)持续关注法

这种方法要求任何程序员在任何时间做任何事情时,都要设法保证系统的高性能。

这种方法看起来很常见,感觉上很有吸引力,但通常不会起太大作用。

(3)性能优化阶段

编写程序时,不用将过多的精力关注在性能上,在代码开发完毕之后,会有一个性能优化阶段,一旦进入该阶段,就按照某个特定程序来调整程序性能。

在性能优化阶段,首先应该用一个度量工具来监控程序的运行,让它告诉你程序中哪些地方大量消耗时间和空间。这样就可以找出性能热点所在的一小段代码。然后应该集中关注这些热点代码,并使用持续关注法中的优化手段来优化它们。每走一步都需要编译、测试、再次度量。

8、重构起源何处

第三章 代码的坏味道

1、重复代码

同一个类中两个函数含有相同的表达式时,就要提炼出重复的代码,然后让这两个地点都调用被提炼出来的那一段代码。

2、过长函数

间接层所带来的全部利益,解释能力、共享能力、选择能力。

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

(1)提炼函数

(2)以查询取代临时变量

(3)引入参数对象或保持对象完整

(4)以函数对象取代函数

将这个特函数放进一个单独对象中,如此一来局部变量就变成了了对象内的字段,然后你可以在同一个对象中将这个大型函数分解成多个小型函数。

本书在不断强调小型函数的优美动人。

(5)条件表达式和循环常常也是提炼的信号。

分解条件表达式;

将循环和其内的代码提炼到一根独立函数中。

3、过大的类

如果想利用单个类做太多事情,其内就会出现太多实例变量。一旦如此,重复代码也就接踵而至了。

可以利用提炼类将几个变量一起提炼至新类中。

4、过长参数列

5、发散式变化

6、散弹式修改

如果遇到某种变化,都必须在很多不同的类中做一些小修改的时候,你就可以将这些一起变化的代码提炼到一个新的类中。

7、依恋情节

函数对某个类的兴趣高多对自己所处类的兴趣,这时就需要转移函数的位置了。

8、数据泥团

一个好的评判方法是:删除众多数据中的一项时,其它数据有没有因而失去意义?如果它们不再有意义,这就是一个明确的信号,你就应该产生一个新对象。

减少字段和参数的个数,当然可以去除一些坏味道,但更重要的是:一旦拥有新对象,就有机会让程序散发出一种芳香。得到新对象后,你就可以着手寻找依恋情节,这可以帮你指出能够移至新类中的种种程序行为。不必太久,所有的类都将在它们小小社会中充分发挥价值。

9、基本类型偏执

对象技术的新手通常不愿意在小任务上运用小对象,像结合数值和币种的money类、电话号码、邮政编码等的特殊字符串,看似简单,此时可以运用以对象取代数据值,将原本单独存在的数据值替换为对象,从而走出传统的洞窟,进入炙手可热的对象世界。

10、switch惊悚现身

面向对象程序的一个最明显特征就是:少用switch语句。

从本质上说,switch语句的问题在于重复。你常会发现同样的switch语句散布于不同地点。如果要为它添加一个新的case子句,就必须找到所有switch语句并修改它们。 面向对象中的多态就可以带来优雅的解决方法。

11、平行继承体系

如果你发现一个类增加一个子类,必须也为另一个类相应的增加一个子类。如果你发现某个继承体系的类名称前缀和另一个继承体系名称前缀完全相同,便是闻到了这种坏味道。

消除这种重复性的一般策略是:让一个继承体系的实例引用另一个继承体系的实例。如果再接再厉运用转移方法和转移字段,就可以将引用端的继承体系消匿于无形。

12、冗余类

折叠继承体系;

将类内联化;

13、夸夸其谈未来性

14、令人迷惑的暂时字段

15、多度耦合的消息链

16、中间人

17、暧昧关系

18、异曲同工的类

19、不完美的类库

引入外加函数,即对复杂参数的封装;

引入本地扩展,即继承类库并添加你需要的方法;

20、纯稚的数据类

21、被拒绝的馈赠

以委托替代继承。

22、过多的注释

当你看到一堆注释的时候,往往是因为你的代码很糟糕,需要用注释去解释它。所以过多的注释就预示着你该对代码进行重构了。

当你感觉需要撰写注释时,请先尝试重构,试着让所有注释都变得多余。

第四章 构筑测试体系

1、自测试代码的价值

实际上编写测试代码的最有用时机是在开始编程之前。当你需要添加特性的时候,先写相应测试代码。

编写测试代码其实就是在问自己,添加这个功能需要做些什么。编写测试代码还能使你把注意力集中于接口而非实现。

2、JUnit测试框架

3、添加更多测试

  • 编写未臻完善的测试并实际运行,好过对完美测试的无尽等待;
  • 考虑可能出错的边界条件,把测试火力集中在那儿;
  • 当事情被认为应该会出错时,别忘了检查是否抛出了预期的异常;
  • 不要因为测试无法捕捉所有bug就不写测试,因为测试的确可以捕捉到大多数bug;

 

上一篇:【编写高质量代码:改善Java程序的151个建议】

下一篇:《重构 改善既有代码的设计 2》重新组织函数、数据

《重构 改善既有代码的设计》读书笔记及心得体会 《重构 改善既有代码的设计》读书笔记及心得体会第一章 重构 第一个案例 重构的第一步,为即将修改的代码建立一组可靠的测试环境。 过程和方法对于项目的结果只有次要的影响,首要的影响是人 没有可靠的测试环境就不要进行代码的重构,那么问题来了: - 什么是可靠的测试环境? 在第四章给出回答 重构时,每次修改的幅度要小,这样便于进行测试发现错误。 这是本书中贯穿始终的 阅读详情

相关推荐

重构:改善既有代码的设计(一)

重构:改善既有代码的设计(一)

不甘于平凡的溃败的博客 1391

重构 :改善既有代码的设计

笔记,回顾

DuGuYiZhao的博客 3876

从零开始用飞牛fnas搭建集成DeepSeek-R1的远程AI工作台

从零开始用飞牛fnas搭建集成DeepSeek-R1的远程AI工作台

AI+全栈,AI+应用,实操落地,前沿技术 3806

重构:改善既有代码的设计

1. 提炼函数 1.1 提炼函数的动机 何时重构:需要花时间才能弄懂一段代码 对于api,我们不需要去弄明白代码如何实现,只需要知道功能,则不需要重构 大量短小函数会让程序跑的更快,更容易被缓存 当函数超过10行就应该考虑提炼函数 1.2 做法 创造新函数,根据意图进行命名(”做什么“来命名,而不是“怎么做”命名) 将待提炼代码复制到新的函数中 若提炼的代码引用了作用域限于源函数,则以参数的形式传递给新函数 在源函数中,将被提炼代码段替换为对目标函数的调用 测试 若其他代码与被提炼代码有相似处,使用以

weixin_44390164的博客 1175

Modscan32连接上了却没数据?一文拆解所有报错(从“Device NOT CONNECTED”到“Checksum Error”)

本文深入解析Modscan32连接异常问题,从状态栏报错到数据异常,提供系统化的诊断思路和解决方案。涵盖物理层问题、配置参数错位、端口占用冲突等常见故障,帮助工程师快速定位和解决Modbus通信中的各类错误。

weixin_30384217的博客 397

S32DS IDE调试技巧:如何用Attach功能高效定位汽车电子MCU的Bootloader问题

本文详细介绍了在汽车电子MCU开发中,如何利用S32DS IDE的Attach调试模式高效定位Bootloader与应用程序的协同问题。通过对比常规调试与Attach模式的本质差异,并深入讲解工程配置、镜像合并及实战调试流程,帮助开发者在不复位、不重新下载程序的前提下,实时分析系统状态,快速解决内存映射冲突、中断向量表重定向等疑难杂症。

weixin_29168393的博客 266

重构,改善既有代码的设计(实战篇)

程序员必懂的代码重构(理论篇)一文介绍了代码重构是什么、常用的重构手法和代码中的“坏味道”。But talk is cheap. Show me the code,本文将从实战的角度来谈谈代码重构,共分为:题目、初步解法、重构实战和总结四部分。

云瀚的自习室 4982

机器视觉检测到底怎么做,经验分享

笔者做机器视觉检测已经有五六年了,也算是对机器视觉的检测技术有了一定的掌握。总的来说,基于机器视觉的检测技术主要包含三个部分:视觉采集模块、后台分析模块和动作决策模块。这几个分类,跟教科书上的有较大差异,很多同学觉得我在杜撰。笔者也不作反驳,因为这是笔者这些年工作经验的总结,自然区别于教科书。下面我们分开来讲这几个模块,同时会把笔者之前的论文做个推荐总结。 所有文章均可在博主的主页中找到,若无法找到,可以用搜索工具。博主的主页: https://blog.youkuaiyun.com/Aoulun 第..

Aoulun的博客 8676

重构 - 改善既有代码的设计

内联函数目的:将意图与实现分开。意图 == 主干;实现 == 分支的实现场景:如果需要花时间浏览一段代码才能弄清它到底干什么,那么就应该将其提炼到一个函数中,并根据它所做的事为其命名。以后再读到这段代码时,可以一眼就能知道函数的用途,大多数根本不需要关心函数如何实现。

梦心之魂的博客 1720

【Kingbase人大金仓】授权文件更换

本文介绍了金仓数据库授权文件更换的步骤:1.通过ksql或客户端工具查询数据库版本;2.在官网下载对应版本的license.bat文件;3.替换前先备份原授权文件(使用tar命令压缩),再用新文件覆盖原文件。注意事项包括:版本号需严格对应,授权文件通常位于安装目录下,可使用find命令查找具体位置。操作需谨慎,建议先备份原文件以便恢复。

qq_34463511的博客 3458

海康威视工业相机SDK二次开发实战:多相机同步采集与图像存储

本文详细介绍了海康威视工业相机SDK二次开发实战,包括多相机同步采集与图像存储的优化方案。通过MVS软件搭建开发环境,实现硬件与软件触发同步采集,并提供高效的图像存储管理技巧,帮助开发者提升工业视觉项目的效率与稳定性。

weixin_29168813的博客 666

《重构 改善既有代码的设计 1》重构原则,如何才能通过一线互联网公司面试

事不过三,三则重构 添加功能时重构 修改错误时重构 复审代码时重构 4、为什么重构有用 难以阅读的程序,难以修改; 逻辑重复的程序,难以修改; 添加新行为时需要修改已有代码的程序,难以修改; 带复杂条件逻辑的程序,难以修改; 因此,我们希望程序: 容易阅读; 所有逻辑都只在唯一地点指定; 新的改动不会危及现有行为; 尽可能简单表达条件逻辑; 间接层和重构 间接层的价值: 允许逻辑共享; 分开解释意图和实现; 隔离变化; 封装条件逻辑..

m0_64867293的博客 202

【深度学习】什么是交叉注意力机制?

输入序列:自注意力机制在同一个输入序列内建立注意力,交叉注意力机制在不同的输入序列间建立注意力。应用场景:自注意力机制多用于单一模态的任务(如纯文本任务),交叉注意力机制多用于多模态任务(如图像和文本的结合)。计算过程:自注意力机制的查询、键和值都来自同一个输入序列,而交叉注意力机制的查询来自一个输入序列,键和值来自另一个输入序列。

q742971636的博客 7370

【重构-改善既有代码的设计1】重构原则

重构的定义:重构是对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低修改成本。(使用重构手法,调整软件代码结构!) 两顶帽子:添加新功能,重构;添加新功能,重构;...     (这个过程,你会发现,重构之后,功能的添加会容易的多) 何时重构:事不过三,三则重构!  专门抽出开发时间出来重构都是不应该的,重构应该随时随地的进行。     添加功能时重构;

Geek马走日 297

智能体开发套件(ADK)介绍

city } ---") city_normalized = city . lower() . replace(" " , "") # 模拟天气数据库 mock_weather_db = {

lpfasd123的博客 1403

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C-重构:改善既有代码的设计之第1章:重构,第一个示例

重构的出发点不是“代码不够漂亮”,而是“下一次修改已经被当前结构拖慢”。测试让重构敢于前进,小步和反馈让错误容易被发现。提炼函数不是搬家,而是把脑中的“这段代码在做什么”变成代码中的命名边界。先把业务事实算成一份稳定数据,再让不同格式各自渲染,是隔离变化的关键一步。多态不是为了炫技,而是把反复出现的“按类型选择规则”收拢到更稳定的结构里。重构的价值来自未来的理解和修改需求;没有变化压力时,不必为了美观强行改动。测试必须能自我检验,重构过程保持“构建、测试、提交”的短循环。

常驻客栈的博客--嵌入式EtherCAT 362

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

《重构 改善既有代码的设计》之重构原则

1 简介 过年回家了,在家里已经呆了两天,两天里陪父母烧锅,教他们使用红米手机,聊天,吃饭。家里很好,只是父母年纪又大了一岁,很心疼它们,听他们讲年后还要出去打工挣钱,不知道说什么,觉得很对不起他们。我真的是太没用了。父亲总是吸烟,烟瘾很重,一晚上要吸很多根,我很担心,但总是劝不停。两天没有总结这本刚看完的《重构》了,所以今晚上,虽然很冷,还是坐在椅子边上认真的敲一些字,总结一下吧。 重构 改善既...

不当初 2165

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

重构-改善既有代码的设计:重构原则(二)

1.什么是重构 重构(Refactoring):在不改变软件的功能和外部可见性的情况下,为了改善软件的结构,提高可读性、可扩展性和复用性性而对软件进行的改造,对代码内部的结构进行优化。 2.为何重构 1)改进软件设计(整理代码) 重构和设计是相辅相成的,它和设计彼此互补。有了重构,你仍然必须做预先的设计,但是不必是最优的设计,只需要一个合理的解决方案就够了,如果没有......

黄规速博客:学如逆水行舟,不进则退 1万+

读《重构:改善既有代码的设计》的思考

重构不是一个一蹴而就的事,需要长期的实践和经验才能够完成得很好。我们重构强调的是 使代码变得更好,拥有代码洁癖。

简单猿 2662

[重构] 改善既有代码的设计

在做微服务拆分相关的课题,会涉及到模块化重构和代码重构相关的东西,重构的速度和质量很大程度上取决于代码原本质量的好坏,所以看了一下这本书,有些知识点我也不知道,所以摘抄了其中比较重要的部分规则。 文章目录重构——改善既有代码的设计序前言第1章 重构,第一个案例第2章 重构原则第3章 代码的坏味道第4章 构筑测试体系第5章 重构列表第6章 重新组织函数第7章 在对象之间搬移特性第8章 重新组织数据第...

Blanchedingding的博客 689

《重构 改善既有代码的设计》之重构列表

1 简介 春节期间,自己也没有阅读其他的书籍,一方面是因为家里没有空调,读书写字时很冷,另外一方面就是灯光不亮,看书时很累眼睛,最后就是在家里总是无聊,心很浮躁,静不下来学习,所以也没有看其他的书籍。 在阅读完《重构 改善既有代码的设计》自己陆续写了一些博客,当然,很多时候只是一种整理,也可以说是一种变相的温故而知新吧。 读完本书时,有一些重构手法给我留下了很深刻的印象,诸如在重新组织函数节的Ex...

不当初 1162
上一篇: 【Java集合 3】List<T>和List<?>的区别
下一篇: 《重构 改善既有代码的设计 2》重新组织函数、数据
哪 吒
哪 吒 2022年度博客之星TOP 1 2022年度博客之星TOP 1 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 59万+粉丝 2935原创
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值