重构-读书笔记

定义

重构是在不改变软件可观察行为的前提下改善其内部结构。

image-20211029112223087

任何不会被修改的变量都可以当成参数传入新的函数,会被修改的变量要格外小心。

如果只有一个变量会被修改,可以把它当做返回值。

尽量去除临时变量,因为临时变量会被当成参数传来传去,容易跟丢它们。

image-20211029155756328

image-20211029162200580

第三章-代码坏味道

  1. 重复代码
    1. 同一个类的两个函数含有相同的表达式
    2. 两个互为兄弟的子类内含相同表达式
    3. 2个毫不相关的类出现重复代码
  2. 过长函数
    1. 每当感觉需要以注释来说明点说明的时候,我们就需要把说明的东西写进一个独立函数中,并以用途命名,不是用实现手法命名。
    2. 有注释的地方就该提炼代码到独立函数中,哪怕只有一行代码。
    3. 条件表达式和循环也可以提炼。可以将循环和其内部代码提炼到独立函数中。

image-20211029163726750

image-20211029163829879

  1. 过大的类,可以将彼此相关的成员变量放到一起,提炼到新的子类。
  2. 过长参数列,尽量将参数放到一个对象中
  3. 少用switch,可以考虑使用多态来替代它
  4. 没用的类可以删掉,不然你所创建的每个类都得有人去理解它,维护它,这都是有成本的。对于几乎没用的类,可以用内部类对付。
  5. 如果一个类的某个实例变量仅为某种特定情况而设置的,这样的代码会让人难以理解,因为在变量未被设置值的时候还需要猜测它的用途,这时候应该把这些变量,和跟这个变量相关的方法抽取到新的类里。
  6. 如果两个函数做同一件事,确有不同的函数命名,应该根据用途,将函数重新命名,并且移入相关的类中,直到两者表达的含义正确。
  7. 过多的注释,当你感觉需要些注释时,尝试先重构,试着让所有注释都变得多余。注释可以写为什么要做某某事。

第六章-组织函数

提炼函数

定义:将代码放进一个独立函数中,并用函数名称解释该函数的用途。

当看到一个过长的函数或者需要一段注释才能理解的代码时,就可以考虑提炼函数。

函数简短的好处:

  1. 函数的粒度越小,越容易被复用,复写也会更容易。
  2. 高层函数读起来就像读一系列注释。

关键:

  1. 函数命名一定要正确,如果提炼可以强化代码的清晰度就可以做。
  2. 函数命名要以他做什么来命名,而不是它怎么做,如果你想不出有意义的命名就别动。
  3. 无局部变量则直接提炼函数即可
  4. 如果有局部变量,但是新函数只是读取它,并不修改它,那就当做参数传给目标函数。
  5. 如果对局部变量发生赋值操作,如果变量只是在被提炼代码中使用,可以将变量在被提炼代码中声明。否则就让目标函数返回该变量改变后的值。
  6. 如果被提炼的函数需要返回多个值,那就挑选另外的函数进行提炼,保证返回值只有一个

内联函数

定义: 一个函数的本体与名称同样清楚易懂。在函数调用点插入函数本体,然后移除该函数。

关键:

  1. 当函数的内部代码和函数名称同样清晰易读,可以考虑去掉这个函数。

image-20211031140000766

内联临时变量

定义:如果你有一个临时变量,只被一个简单表达式赋值1次,而它妨碍了其他重构手法,那就将所有对该变量的引用动作,替换为对它复制的那个表达式本身。

image-20211031135951399

以查询取代临时变量

定义:你的程序以一个临时变量保存某一表达式的运算结果,那就将这个表达式提炼到一个独立函数中,将这个临时变量的所有引用点替换为对新函数的调用。此后,新函数就可被其他函数使用。

image-20211031135941037

引入解释性变量

你有一个复杂的表达式,将该复杂表达式(或其中一部分)的结果放进一个临时变量,并用此变量名称来解释表达式用途。

image-20211031140615255

分解临时变量

你的程序有某个临时变量被复制超过1次,但是它既不是循环变量,也不是用于收集计算结果,那么针对每次赋值,应该创建一个独立,对应的临时变量。

image-20211031141103421

如果临时变量只是用于保存一段冗长代码的运算结果,以便后续使用,那么这种变量应该只被赋值1次,如果被赋值超过多次,说明这个变量承担了一个以上的责任,会令代码阅读者糊涂,每个变量应该只承担一个责任。

移除对参数的赋值

代码对一个参数进行赋值,那就用一个临时变量取代该参数的位置。

image-20211031141454113

以函数对象取代函数

image-20211031142543518

替换算法

image-20211031142720474

第九章 简化条件表达式

总结

  1. 分解条件表达式,将复杂的的条件提炼出新的函数。
  2. 将可以合并的条件表达式进行合并。
  3. 合并重复的条件片段,抽离出变化和不变的内容。
  4. 使用break和return,卫语句,提前返回函数。
  5. 使用多态替代switch表达式。

分解条件表达式

image-20211108100238340

image-20211108100355063

合并条件表达式

image-20211108100851243

image-20211108101024040

合并重复的条件片段

image-20211108101136036

image-20211108101206817

移除控制标记

image-20211108101449660

使用卫语句,取代嵌套条件表达式

image-20211108101608749

image-20211108101654821

用多态取代条件表达式

image-20211108102128009

image-20211108102202185

image-20211108102220361

引入NULL对象

image-20211108102437652

引入断言

image-20211108103022547

第十章 简化函数调用

总结

  1. 给函数取一个好名字,想办法将注释变成函数名称
  2. 函数入参尽量使用对象,保证入参的简短。
  3. 将查询函数和修改函数分开,一个负责查询,一个负责修改
  4. 用异常取代错误码,可以预先检查的条件,可以在调用函数之前先做检查,即提前返回函数
  5. 如果函数做了类似的工作,那就建立单一的函数,通过参数表达不同的值
  6. 如果参数可以通过函数获取,则去掉该参数,改为通过函数获取。
  7. 如果函数没有被其他类使用,则设置为private

函数改名

image-20211101145348412

添加参数

image-20211101172652005

移除参数

和添加参数同理

将查询函数和修改函数分离

image-20211101172849403

image-20211101172931926

注意并发问题

image-20211101173419688

令函数携带参数

image-20211101173449475

image-20211101173544703

以明确函数取代参数

image-20211101174524273

尤其是switch或者if分支的用途

image-20211101174914376

保持对象完整

image-20211101175003239

image-20211101175124758

以函数取代参数

image-20211103163518271

image-20211103163602213

引入参数对象

image-20211103163927717

移除设值函数

image-20211103164224862

image-20211103164239042

隐藏函数

image-20211103164315875

以工厂函数取代构造函数

image-20211103165256285

封装向下类型

image-20211103165453487

用异常取代错误码

image-20211103165620714

以测试取代异常

image-20211103165805762

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值