(笔记来自于《重构 改善既有代码的设计》)
要点
一、何谓重构
二、为何重构
三、何时重构
四、重构难点
五、重构分类
一、何谓重构
对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
二、为何重构
1、重构改进软件设计:整理代码
2、重构使软件更容易理解:不给后人留坑
3、重构帮助找到bug
4、重构提高编程速度:更迅速地添加新功能
三、何时重构
1、三次法则:第三次做类似的事,就应该重构
2、添加功能时重构:添加功能前重构可更快速的理解代码
3、修补错误时重构:提高可读性,一眼看出bug
4、复审代码时重构
四、重构难点
1、数据库:数据库结构和对象模型间的依赖
2、修改接口:用旧接口调用新接口
3、设计改动
4、不改重构的情况:代码及其混乱,不能正常运行,项目最后期限
五、重构分类(页码为中文书页码)
1、Duplicated Code(重复代码)
常见情况:同一个类的两个函数含有相同的表达式(Extract Method(110))、两个互为兄弟的子类内含相同的表达式(Extract Method(110),Pull Up Method(332),Form template Method(354),Substitute Algorithm(139))、两个毫不相关的类(Extract Class(149))
2、Long Method(过长函数)
常见情况:提炼函数(Extract Method(110))、大量的参数和临时变量(Replace Temp with Query(120))、过长参数列(Introduce Parameter Object(295),Preserve Whole Object(288))、杀手锏(Replace Method with Method Object(135))、条件表达式和循环(Decompose Conditional(238))
3、Large Class(过大的类)
常见情况:变量提炼(Extract Class(149))或适合作为子类(Extract Subclass(330))、提炼接口(Extract Interface(341))、两边各保留一些重复数据,并保持两边同步(Duplicate Observed Data(189))
4、Long Parameter List(过长参数列)
常见情况:用请求取代参数(Replace Parameter with Method(292))、用已有对象替换一堆参数(Preserve Whole Object)、制造参数对象(Introduce Parameter Object(295))
5、Divergent Change(发散式变化)
常见情况:修改某一部分需要对类中很多函数进行修改,考虑分为多个类(Extract Class(149))
6、Shotgun Surgery(霰弹式修改)
常见情况:与5相反,修改某一部分需要对很多类中进行修改,放入同一类(Move Method(142),Move Field(146))或新建一个类(Inline Class(154))但可能出现5情况
7、Feature Envy(依恋情结)
常见情况:函数对其他类的意义高过自身类的意义?移动函数所处地点(Move Method(142))或提炼到独立函数中(Extract Method(110))
8、Data Clumps(数据泥团)
常见情况:多个数据经常一起作为参数出现,提炼一个独立的对象中(Extract Class(149))、减肥(Introduce Parameter Object(295)或Preserve Whole Object(288))
9、Primitive Obsession(基本类型偏执)
常见情况:独立存在的数据值替换为对象(Replace Data Value with Object)、类型码(Replace Type Code with Class)、与类型码相关的条件表达式(Replace Type Code with Subclass(213),Replace Type Code with State/Strategy(227))、一组总是放在一起的字段(Extract Class(149),Introduce Parameter Object(295))、数组(Replace Array with Object(186))
10、Switch Statements(switch惊悚现身)
常见情况:用多态,用函数代替(Extract Method(110))、搬移到多态性的类中(Move Method(142))、(Replace Type Code with Subclasses(223)、Replace Type Code with State/Strategy(227))、(Replace Conditional with Polymorphism(255)),不需要用多态时(Replace Parameter with Explicit Method(285)),如果选择条件之一是null(Introduce Null Object(260))
11、Parallel Inheritance Hierarchies(平行继承关系)
常见情况:为某个类增加子类,同时必须为另一个类增加子类,让一个继承体系的实例引用另一个继承体系的实例?(Move Method(142),Move Field(146))
12、Lazy Class(冗赘(zhui,第四声)类)
常见情况:存在意义不大的类(Collapse Hierarchy(344), Inline Class(154))
13、Speculative Generality(夸夸其谈未来性)
常见情况:某个抽象类没有太大意义(Collapse Hierarchy(344))、函数某些参数未被用上(Remove Parameter(277))、函数名称带有多余的抽象意味(Rename Method(273))
14、Temporary Field(令人迷惑的暂时字段)
常见情况:对象的某个实例变量仅为某种特定情况而设,创建一个类(Extract Class(149))、创键一个Null对象(Introduce Null Object(260))、将算法函数的长参数提炼到类中(Extract Class(149))(貌似重复)
15、Message Chains(过度耦合的消息链)
常见情况:对象找对象,找下一个对象,再下一个对象,结构过于耦合(Hide Delegate(157))、提炼到函数中(Extract Method(110),Move Method(142))
16、Middle Man(中间人)
常见情况:过度运用委托的类(Remove Middle Man(160))、放进调用端(Inline Method(117))、变成对象的子类(Replace Delegation with Inheritance(355))
17、Inappropriate Intimacy(狎(xia第二声)昵关系)
常见情况:两个类过于亲密,划清界限(Move Method(142),Move Field(146))、断绝关系(Change Bidirectional Association to Unidirectional(200))、合并类(Extract Class(149))、创建中间类(Hide Delegate(157))
18、Alternative Classes with Different Interface(异曲同工的类)
常见情况:两个函数做同一件事,重新命名(Rename Method(273))、某些行为移入类(Move Method(142))、超类(Extract Superclass(336))
19、Incomplete Library Class(不完美的库类)
常见情况:修改类库的一两个函数(Introduce Foreign Method(162))、添加一大堆额外的行为(Introduce Local Extension(164))
20、Data Class(纯稚的数据类)
常见情况:仅仅是数据(Encapsulate Field(206))、若内含有容器类的字段(Encapsulate Collection(208))、含有不改被其他类修改的字段(Remove Setting Method(300))、setter/getter搬移到类中(Extract Method(110))、隐藏setter/getter(Hide Method(303))
21、Refused Bequest(被拒绝的遗赠)
常见情况:子类不需要继承父类的一些实例变量或函数,子类创建一个兄弟类然后(Push Down Method(328),Push Down Field(329)),子类不愿支持超类接口(Replace Inheritance with Delegation(352))
22、Comments(过多的注释)
常见情况:提炼函数(Extract Method(110))、(Rename Method(273))、注释说明某些系统的需求规格(Introduce Assertion(267))