重构 's 读书笔记
整理对于《重构-改善既有代码的设计》一书的读书笔记
asing1elife
life is simple, just coding.
展开
-
3.1 Duplicated Code 重复代码
在一个以上的地方看到了相同的代码结构,则视为重复代码同一个类的两个方法含有相同的表达式使用 6.1 Extract Method 提炼方法 提炼出重复的代码,放置到新方法中让两个方法都调用该新方法两个继承相同父类的子类含有相同的表达式EX1对两个子类都使用 6.1 Extract Method 提炼方法 提炼出重复的代码,放置到新方法中对新方法使用 11.2 Pull U...原创 2018-10-25 19:26:22 · 2006 阅读 · 0 评论 -
3.2 Long Method 过长方法
程序越长越难理解,小型方法价值更大注释通常可以指出代码用户和实际手法之间的语义距离使用 6.1 Extract Method 提炼方法 将方法中适合集中在一起的部分,提炼到新方法中若上述提炼导致大量的参数和临时变量转化为新方法的形参,则应该使用 6.4 Replace Temp with Query 以查询取代临时变量 消除这些参数及变量10.9 Introduce Paramete...原创 2018-10-25 19:30:44 · 269 阅读 · 0 评论 -
3.3 Large Class 过大的类
对于单个类来说,其处理了过多的逻辑,则会形成过大的类类如果有太多代码,也是代码重复、混乱并最终走向死亡使用 7.3 Extract Class 提炼类 将类中的实例变量提炼至新类中,注意相关联的变量应该存放在一起如果这个新类适合作为一个子类,则使用 11.6 Extract Subclass 提炼子类 更方便...原创 2018-10-25 19:31:52 · 407 阅读 · 0 评论 -
3.4 Long Parameter List 过长参数列
方法拥有过多的形参将导致方法本身难以理解,不易使用,而且一旦需要更多数据,则必须继续添加参数列,导致问题变得更加严重方法的参数可以通过向已有对象发起一条请求而取代使用 10.8 Replace Parameter with Methods 以方法取代参数 将方法的形参进行替换使用 10.7 Preserve Whole Object 保证对象完整 将来自同一个对象的一堆数据进行收集,并...原创 2018-10-25 19:32:55 · 221 阅读 · 0 评论 -
3.5 Divergent Change 发散式变化
如果在想修改代码逻辑时无法成功定位到具体某一点,则存在发散式变化的问题某个类经常因为不同的原因在不同的方向上发生变化找出造成所有变化的特定原因,使用 7.3 Extract Class 提炼类 将其提炼到新类中...原创 2018-10-25 19:33:29 · 578 阅读 · 0 评论 -
3.6 Shotgun Surgery 散弹式修改
一个需求变化会引发多个类进行相应修改,则为散弹式修改每次遇到某种变化,都必须在许多不同的类做出许多小修改使用 7.1 Move Method 迁移方法 和 7.2 Move Field 迁移字段 将所有需要修改的代码放进同一个类进行处理若当前不存在这么一个类,则创建一个一些关联情况3.5 Divergent Change 发散式变化 是指一个类受到多种变化的影响3.6 Sho...原创 2018-10-25 19:34:40 · 677 阅读 · 0 评论 -
3.7 Feature Envy 依恋情结
数据本身和对数据的操作没有包装在同一个类中,则形成依恋情结方法对某个类的兴趣大于对自己所处类的兴趣使用 7.1 Move Method 迁移方法 将该方法移至他应该属于的类方法的一部分更适合于其被频繁调用的类使用 6.1 Extract Method 提炼方法 将这一部分代码提炼至单独方法使用 7.1 Move Method 迁移方法 将新方法移至被调用的类关键点判断哪...原创 2018-10-25 19:35:35 · 710 阅读 · 0 评论 -
3.8 Data Clumps 数据泥团
太不同的类中出现重复的字段或参数,则表明形成了数据泥团多个类中出现相同的字段,或多个方法上出现相同的形参1. 使用 [7.3 Extract Class 提炼类](bear://x-callback-url/open-note?id=680267A8-B00F-4850-8AB5-E8D01FAA85B6-1896-000010CAF93E04A6) 将这些字段提炼至独立对象中2. 使用...原创 2018-10-25 19:36:49 · 555 阅读 · 0 评论 -
3.9 Primitive Obsession 基本类型偏执
刚接触面向对象时大部分情况都不愿意使用小对象去处理运用场景一些基本类型的数值存在一定关联1. 使用 [8.2 Replace Data Value with Object 以对象取代数据值](bear://x-callback-url/open-note?id=F5CBD84A-EFA1-42F3-B3E4-08913CA77629-339-00000AE93BC2E0BC) 将原本独立存...原创 2018-10-25 19:39:17 · 789 阅读 · 0 评论 -
3.10 Switch Statements 声明选择结构
在面向对象中应该尽量少使用 switch 结构,从本质上来说,switch 结构的弊端在于重复,而多态是 switch 结构的优雅解决方式一段重复的选择结构在多个类中被使用1. 使用 [6.1 Extract Method 提炼方法](bear://x-callback-url/open-note?id=00044784-3DD8-420A-B97F-C495A6C36E2A-1896-0...原创 2018-10-25 19:42:34 · 137 阅读 · 0 评论 -
3.11 Parallel Inheritance Hierarchies 平行继承关系
其实就是 3.6 Shotgun Surgery 散弹式修改 的特殊情况为某个类添加一个子类,也必须为另一个类相应增加一个子类让一个继承体系的实例引用另一个继承体系的实例使用 7.1 Move Method 迁移方法 和 7.2 Move Field 迁移字段 将引用端的继承体系逐个消除...原创 2018-10-26 09:28:36 · 497 阅读 · 0 评论 -
3.12 Lazy Class 冗余类
某个类的价值低于为他花费的维护成本,则形成冗余类某些类没有起到足够的作用使用 11.9 Collapse Hierarchy 折叠继承体系 将用处太小的类进行精简某些组件完全失去作用使用 7.4 Inline Class 将类内联化 将这些组件移除...原创 2018-10-26 09:29:34 · 261 阅读 · 0 评论 -
3.13 Speculative Generally 夸大未来性
提前准备某些类,却一直未使用过某个抽象类基本没什么作用使用 11.9 Collapse Hierarchy 折叠继承体系一些不必要的调用关系使用 7.4 Inline Class 将类内联化方法的某些参数未被使用使用 10.3 Remove Parameter 移除参数方法的名称带有多余的解释意义使用 10.1 Rename Method 重命名方法...原创 2018-10-26 09:31:06 · 161 阅读 · 0 评论 -
3.14 Temporary Field 临时字段
某些字段只有在某种特定情况下才有效,这就形成了临时字段某个实例变量仅为某种特定情况而设使用 7.3 Extract Class 提炼类 将该变量提炼至新类使用 7.1 Move Method 迁移方法 和 7.2 Move Field 迁移字段 将于该变量相关的方法和字段都迁移至新类...原创 2018-10-26 09:32:36 · 322 阅读 · 0 评论 -
3.15 Message Chains 高耦合消息链
对象之间的请求路径过长,就容易导致高耦合消息链的出现一个对象请求另一个对象,然后再向后者请求另一个对象,周而复始观察消息链最后得到的对象具体是什么使用 7.3 Extract Class 提炼类 将获取结果的代码提炼至新类使用 7.1 Move Method 迁移方法 将新类的中的新方法推入消息链之后再有其他对象想获取该结果,直接调用该类即可,无需依次调用相关类...原创 2018-10-26 09:33:17 · 326 阅读 · 0 评论 -
3.16 Middle Man 中间人
过度使用委托,导致存在多余的中间类某个接口有一半的方法都委托给其他类使用 7.6 Remove Middle Man 移除中间人 将中间类去除,让两个类直接建立联系某个接口中只有少数几个方法委托给其他类使用 6.2 Inline Method 内敛方法 将这些方法直接移至调用端接口中的方法虽然被多次委托,但被委托的方法还存在其他行为使用 11.12 Replace Del...原创 2018-10-26 09:34:16 · 184 阅读 · 0 评论 -
3.17 Inappropriate Intimacy 狎昵关系
两个类之前过于亲密就容易导致不适当的狎昵关系两个类之间相互调用过多方法使用 7.1 Move Method 迁移方法 和 7.2 Move Field 迁移字段 将被调用的类或字段迁移至调用端使用 8.8 Change Bidirectional Association to Unidirectional 将双向关联改为单向关联 将一个被调用端的方法移至调用端,从而结束相互关联使用 ...原创 2018-10-26 09:35:51 · 462 阅读 · 0 评论 -
3.18 Alternative Classes with Different Interfaces 异曲同工的类
两个类的内部逻辑基本相同,却有着不同的名字两个方法做着同一件事,却拥有不同的名称使用 10.1 Rename Method 重命名方法 根据他们的用途命名反复使用 7.1 Move Method 迁移方法 将对应的行为移入到对应得类,知道两者的用处一致为止如果上述动作重复次数过多,可以考虑使用 11.7 Extract Superclass 提炼父类 将这些共有行为提炼至父类中...原创 2018-10-26 09:37:45 · 358 阅读 · 0 评论 -
3.19 Incomplete Library Class 不完美的类库
类库构造的不够完善完善类库中的一两个方法使用 7.7 Introduce Foreign Method 引入外部方法晚上类库的大部分行为使用 7.8 Introduce Local Extension 引入本地扩展...原创 2018-10-26 09:38:43 · 401 阅读 · 0 评论 -
3.20 Data Class 幼稚的数据类
某些类拥有一些字段,以及访问/读写这些字段的方法,除此之外没有其他用处,则称为数据类存在修饰符为 public 的字段使用 8.10 Encapsulate Field 封装字段 将这些字段进行封装存在修饰符为 public 的集合使用 8.11 Encapsulate Collection 封装集合 将这些集合进行封装某些字段不应该被其他类修改使用 10.10 Rem...原创 2018-10-26 09:39:40 · 639 阅读 · 0 评论 -
3.21 Refused Bequest 被拒绝的馈赠
子类复用了父类的实现,却不愿支持父类的接口继承体系设计错误使用 11.5 Push Down Field 字段下移 和 11.4 Push Down Method 方法下移 把所有子类用不到的方法和字段从父类中迁移到另一个子类中...原创 2018-10-28 10:46:20 · 1031 阅读 · 0 评论 -
3.22 Comments 过多的注释
为了解释某段代码的意义,而编写了过多的注释,这反而从另一方面说明这段代码需要被重构某段代码需要过多的注释进行描述使用 6.1 Extract Method 提炼方法 根据注释的描述将方法进行提炼,从而让拥挤的注释变的相对零散方法被提炼后依旧需要注释进行说明使用 10.1 Rename Method 重命名方法 尝试使用方法名解释方法用途...原创 2018-10-28 10:47:18 · 209 阅读 · 0 评论 -
4.1 自测代码的价值
更多精彩更多技术博客,请移步 asing1elife’s blog一些关键点确保所有测试都完全自动化,让它们检查自己的测试结果,如果测试到最后还需要自己去比对结果,那么这个测试其实反而降低了开发效率一套测试就是一个强大的 bug 侦测器,能够大大缩减查找 bug 花费的时间...原创 2018-10-28 10:47:37 · 188 阅读 · 0 评论 -
4.2 JUnit 测试框架
更多精彩更多技术博客,请移步 asing1elife’s blog一些关键点每次添加新功能后,都应该为其编写一套测试方法每次收到 bug 报告时,都应该先写一个单元测试用于暴露 bug...原创 2018-10-28 10:47:58 · 171 阅读 · 0 评论 -
4.3 添加更多测试
更多精彩更多技术博客,请移步 asing1elife’s blog一些关键点编写测试代码也是一个需要不断优化的过程,但目的是一致的,都为了提高开发效率编写测试代码时需要考虑错误边界在那,尽可能模拟出这些情况,提高测试程序的健壮性当测试程序抛出异常时,也需要检查是否是那个预期的异常不能指望测试可以捕捉到所有 bug...原创 2018-10-28 10:48:49 · 150 阅读 · 0 评论 -
5.1 重构的记录格式
更多精彩更多技术博客,请移步 asing1elife’s blog重构内容的组成name - 名称summary - 概要motivation - 动机mechanics - 做法examples - 范例原创 2018-10-28 10:49:07 · 199 阅读 · 0 评论 -
5.2 寻找引用点
该节已不适用于现有开发模式,因为不论是 Eclipse 或者是 IDEA 都可以很迅速的找到方法的调用点更多精彩更多技术博客,请移步 asing1elife’s blog原创 2018-10-28 10:49:23 · 150 阅读 · 0 评论 -
5.3 这些重构手法有多成熟
没什么好说的更多精彩更多技术博客,请移步 asing1elife’s blog原创 2018-10-28 10:49:44 · 200 阅读 · 0 评论 -
6.1 Extract Method 提炼方法
将这段代码放进一个独立方法中,并让方法名称解释该方法的用途更多精彩更多技术博客,请移步 asing1elife’s blog动机一个过长的方法或一段需要注释才能让人理解用户的代码,就应该被放进一个独立方法优点如果每个方法的粒度都很小,那么方法被复用的机会就更大使高层方法读起来像一系列注释如果方法都是细粒度,那么方法被覆写就更容易案例public void pri...原创 2018-10-28 10:50:01 · 300 阅读 · 0 评论 -
6.2 Inline Method 内联方法
在方法调用点插入方法本体,然后移除该方法更多精彩更多技术博客,请移步 asing1elife’s blog动机一系列组织不合理的方法相互调用,可以通过内联方法将其合并成一个大型方法,在通过 6.1 Extract Method 提炼方法 将这些代码重新提炼过多的使用间接层,导致系统中大部分方法看上去都只是另一个方法的简单委托案例public int getRating()...原创 2018-10-28 10:50:38 · 348 阅读 · 0 评论 -
6.3 Inline Temp 内联临时变量
将所有对该变量的引用动作替换为对它赋值的表达式更多精彩更多技术博客,请移步 asing1elife’s blog前置条件该方法通常被作为 6.4 Replace Temp with Query 以查询取代临时变量 的前置条件使用动机某个临时变量被赋予了某个方法的返回值案例public double getBasePrice() {double basePrice ...原创 2018-10-30 10:31:03 · 218 阅读 · 0 评论 -
6.4 Replace Temp with Query 以查询取代临时变量
将表达式提炼到一个独立方法中,将这个临时变量的所有引用点替换为对新方法的调用更多精彩更多技术博客,请移步 asing1elife’s blog前置条件该方法通常是 6.1 Extract Method 提炼方法 的前置条件动机临时变量只能在所属方法中使用,它们会促使编写更长的方法案例public double getDiscountPrice() { double...原创 2018-10-30 10:47:12 · 210 阅读 · 0 评论 -
6.5 Introduce Explaining Variable 引入解释性变量
将复杂表达式的结果放进一个临时变量,通过该变量的名称解释表达式的用途更多精彩更多技术博客,请移步 asing1elife’s blog动机表达式可能非常复杂而且难以阅读在较长的算法中可以运用临时变量来解释每一步运算的意义对比相对于该方法,使用 6.1 Extract Method 提炼方法 不断可以对表达式进行解释,而且还提高了表达式的重用性但当 6.1 Extrac...原创 2018-10-30 10:47:51 · 161 阅读 · 0 评论 -
6.6 Split Temporary Variable 分解临时变量
针对每次赋值,创造一个独立、对应的临时变量更多精彩更多技术博客,请移步 asing1elife’s blog动机同一个临时变量承担两件不同的事情,会让代码阅读者无法理解循环变量和结果收集变量最容易产生被多次赋值的可能案例double temp = 2 * (height * width);System.out.println(temp);temp = height ...原创 2018-10-30 10:48:09 · 137 阅读 · 0 评论 -
6.8 Replace Method with Method Object 以方法对象取代方法
将大型方法放入单独对象,使方法内的临时变量成为对象中字段,在对象中将大型方法分解为多个小型方法更多精彩更多技术博客,请移步 asing1elife’s blog前置条件有时候会发现无法使用 6.4 Replace Temp with Query 以查询取代临时变量 ,因为无法拆解一个需要被拆解的对象这个时候就需要先使用本方法,在使用上述方法动机小型方法的复用率更高,且更...原创 2018-10-30 10:48:39 · 186 阅读 · 1 评论 -
6.9 Substitute Algorithm 替换算法
将方法本体替换为另一个算法更多精彩更多技术博客,请移步 asing1elife’s blog动机只是发现了一个更好的方法可以得出相同的结果案例public String foundPerson(String[] people) { for (int i = 0; i < people.length; i++) { if (people[i].equals("Do...原创 2018-10-30 10:48:59 · 220 阅读 · 1 评论 -
7.1 Move Method 迁移方法
将该方法迁移至其最常被引用的类中更多精彩更多技术博客,请移步 asing1elife’s blog动机迁移方法是重构理论的支柱一个方法与其他类的交互更甚于自身所处的类,那么该方法就应该被迁移...原创 2018-10-30 10:49:17 · 443 阅读 · 1 评论 -
7.2 Move Field 迁移字段
在目标类中新建一个字段,修改源字段的所有调用者,让他们引用新字段更多精彩更多技术博客,请移步 asing1elife’s blog前置条件在使用 7.3 Extract Class 提炼类 之前,通常需要使用该方法动机在程序中,某个字段被所驻类之外的另一个类更多的使用在类之间移动状态和行为,是重构过程中必不可少的措施...原创 2018-10-30 10:49:49 · 212 阅读 · 0 评论 -
7.3 Extract Class 提炼类
建立一个新类,将相关字段和方法从旧类迁移到新类更多精彩更多技术博客,请移步 asing1elife’s blog动机某个类做了应该由两个类做的事每个类都用该是一个清楚的抽象,处理一些明确的责任如果搬移了类中的某个字段或方法,对该类并没有任何影响,那么这些字段和方法就应该被提炼...原创 2018-10-30 10:50:09 · 372 阅读 · 0 评论 -
7.4 Inline Class 将类内联化
将这个类所有的特性搬移到另一个类中,然后移除原类更多精彩更多技术博客,请移步 asing1elife’s blog动机某个类没有做太多事情某个类所做的事情完全应该属于一个已存在的类...原创 2018-10-30 10:50:29 · 339 阅读 · 0 评论