重构:改善既有代码的设计 读书笔记

基本定义:重构(名词)是在不改变软件外在行为的前提下改善其内部结构。提高可理解性,降低修改成本。重构(动词)是使用一系列重构手法,在不改变软件外在行为的前提下,调整其结构。

第一章

  1. 如果你需要为程序添加一个新功能,而现有的代码结构使你无法很方便地达成目的,那就需要先重构现有的代码结构。

  2. 重构之前,首先检查自己是否有一套可靠的测试机制。这些测试必须有自我检验能力。

  3. 重构技术就是以微小的步伐修改程序。如果你放下错误,很容易便可以发现它。

第二章

重构的时机:

  1. 添加功能时

  2. 修改错误时

  3. 代码 Review 时

第三章

代码的坏味道:

  1. 重复代码

  2. 过长函数

  3. 过大的类

  4. 过长参数列

  5. 发散式变化:一个类受多个变化的影响

  6. 霰弹式修改:一种变化引起多个类的修改

  7. 依恋情节:引入了过多依赖

  8. 数据泥团:过于相同的对象

  9. 基本类型偏执:为做一两件事而创建的结构会太麻烦,不如采用基本类型

  10. Switch 惊悚现身:尽可能用多态来替换

  11. 平行继承体系

  12. 冗余类

  13. 夸夸其谈未来型:某个抽象类作用不大

  14. 令人迷惑的暂时字段

  15. 过度耦合的信息链

  16. 中间人:过度运用委托

  17. 过度亲密关系:两个类过于耦合

  18. 异曲同工的类

  19. 不完美的库类

  20. 纯数据类:需要封装

  21. 被拒绝的遗赠:子类不实现支持超类的接口

  22. 过多的注释

第六章

重新组织函数

  1. 提炼函数:将过于长的代码放到几个合适的小函数里

  2. 内联函数:内联一些过于简短的函数到原调用方式里

  3. 内联临时变量:临时变量只是简单赋值一次,使用一次

  4. 以查询取代临时变量:将表达式提炼到一个独立函数

  5. 引入解释性变量:表达式难以理解时,引入临时变量来解释用途

  6. 分解临时变量:针对每次赋值,创造一个独立、对应的临时变量

  7. 移除对参数的赋值:对入参如果有修改,用临时变量承载

  8. 以函数对象取代函数:局部变量过多时,可以封装成一个对象来取代操作

  9. 替换算法:将函数本体替换成另外一个算法

第七章

在对象之间搬移特性

  1. 搬移函数:A类的某一个函数与B类过于耦合,则需要考虑将函数移动到B类

  2. 搬移字段:A类的某一个字段与B类过于耦合,则需要考虑将字段移动到B类

  3. 提炼类:某一个类做了应该由两个类做的事,则需要将类进行拆分成立两个类

  4. 内联类:一个类没做太多事情,合并到另一个类

  5. 隐藏“委托关系”:在服务类上建立客户所需的所有函数,用以隐藏委托关系

  6. 移除中间人:某个类做了过多的简单委托动作,需要客户直接调用受托类

  7. 引入外加函数:需要提供服务的类需要添加函数,但无法修改这个类,在客户类中建立一个函数,并将第一参数形式传入一个服务类实例

  8. 引入本地拓展:装饰器模式,来为之前的类新加功能函数

第八章

重新组织数据

  1. 自封装字段:通过为一个字段封装一个函数来代替访问方式

  2. 以对象取代数据值:将一个数据项封装成一个对象

  3. 将值对象改为引用对象:值传递改为引用传递

  4. 将引用对象改为值对象:引用对象很小且不可变不易管理,变成值对象

  5. 以对象取代数组:通过字段名字更能表达数据的用途

  6. 复制“被监视数据”:通过观察者模式来同步一些数据

  7. 将单向关联改为双向关联:两个类需要对方特性时,添加一个反向指针,可以同时更新

  8. 将双向关联改为单向关联:一个类不再需要另一个类的特性,移除不必要的关联

  9. 以字面常量取代魔法数:通过命名来标记用途

  10. 封装字段:对一个 public 字段改为 private, 并提供对应访问函数

  11. 封装集合:返回集合的副本,而不是原来的集合

  12. 以数据类取代记录:为传统编程环境的记录结构建立一个对象

  13. 以类取代类型码:为类型码新建一个类

  14. 以子类取代类型码:以子类取代一个不可变的类型码

  15. 以 State/Strategy 取代类型码:状态模式、策略模式来取代类型码

  16. 以字段取代子类:各个子类区别只在常量数据上,新增字段来销毁子类

第九章

简化条件表达式

  1. 分解条件表达式:从 if then else 中提炼出独立函数

  2. 合并条件表达式:一系列条件测试,返回同样的结果,合并成一个表达式并提炼成函数

  3. 合并重复的条件片段:每个分支都有相同的代码,移到表达式之外

  4. 移除控制标记:以 break 或 return 取代控制标记

  5. 以卫语句取代嵌套条件表达式:提早使用 return 来结束一段逻辑

  6. 以多态取代条件表达式:把分支放到子类里复写函数,将原始函数声明为抽象函数

  7. 引入 Null 对象:将 null 值替换成 null 对象

  8. 引入断言:以断言来表现程序状态的某种假设

第十章

简化函数调用

  1. 函数改名:函数名称自解释

  2. 添加参数:需要新的信息时,添加一个对象参数

  3. 移除参数:不再需要某个参数时,移除该参数

  4. 查询函数与修改函数分离:单一职责原则

  5. 函数携带参数:若干函数做了类似工作,添加一个参数合并这些函数

  6. 以明确函数取代参数:函数完全取决于参数值不同而采取不同行为,针对每一个可能取值,建立独立函数

  7. 保持参数完整:从某个对象取出若干值当入参,改为直接传递整个对象

  8. 以函数取代参数:某个函数的参数是另一个函数的结果,去除该参数,直接调用原函数

  9. 引入参数对象:某些参数总是同时出现,以一个对象取代这些参数

  10. 移除设值函数:某个字段在对象创建时被设值,然后不再改变,去除该字段的设值函数

  11. 隐藏函数:有一个函数从来没被其他类用到,函数修改为 private

  12. 工厂函数取代构造函数:可以在创建对象的时候,执行一些复杂的操作

  13. 封装向下转型:函数返回对象需要向下转型,应将向下转型在该函数中操作

  14. 以异常取代错误码:特定代码表示错误情况,改用异常传递

  15. 以测试取代异常:调用函数时先检查而不是直接抛出异常

第十一章

处理继承关系

  1. 字段上移:两个子类有相同的字段,上移至父类

  2. 函数上移:两个子类有相同的函数,上移至父类

  3. 构造函数本体上移:父类新建一个构造函数,子类去调用

  4. 函数下移:某个函数只与部分子类相关,将函数下放到子类

  5. 字段下移:某些字段只和部分子类有关,下放到子类

  6. 提炼子类:类的某些特性只被部分实例用到,新建一个子类将特性转移到子类中

  7. 提炼超类:两个类有相似特性,提炼出一个父类

  8. 提炼接口:两个类的接口有部分相同,提炼到一个独立接口

  9. 折叠继承体系:父类子类已无太大区别,合为一体

  10. 塑造模板函数:采用模板模式将一些函数封装成模板,子类去复写

  11. 以委托取代继承:子类只使用父类的一部分,组合方式代替继承

  12. 以继承取代委托:两个类有过多的接口以及委托函数,改为继承关系

第十二章

大型重构

  1. 梳理并分解继承体系:某个继承体系同时承担两项责任,建立两个继承体系,并通过委托关系让其中一个可以调用另一个

  2. 过程化设计转化为对象设计:数据记录变成对象,大块行为分为小块,行为移到类中

  3. 模型和显示分离:MVC 模式,将模型与显示分离

  4. 提炼继承体系:某一个类做了太多工作,一部分工作是大量表达式完成的,建立继承体系,以一个子类表示一种特殊情况

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值