《重构》读后感(一)
《重构》是一本简单实用的好书,每个靠写代码领工资的软件工程师都应该读一读。运用重构技术可以帮你写出更好的代码—–这会让你和你同事在阅读、修改代码时轻松很多。
本书写作于1999年,用的JDK版本是1.1,彼时Eclipse还没有诞生,代码重构时的做法还是一步一步按部就班地手工修改代码。现在Eclipse中的Refactoring菜单下已经集成了书中提到的众多常用重构手法,应该是从本书得到了不少借鉴。
第一章 重构,第一个案例
JUnit:测试在重构中非常重要,我们需要依赖测试检查是否引入新bug。
VN、单元测试、回归测试
小幅重构、及时测试,易于发现错误
自动化重构工具:Eclipse
重构手法:
Extract Method
Move Method
委托(delegate)
保留旧函数,让它内部调用新函数(向后兼容)
Replace Temp with Query
Query Method(可以加入cache机制)
运用多态(polymorphism)代替switch语句
Replace Type Code with State/Strategy
Replace Conditional with Polymorphism
第二章 重构原则
1,所谓程序设计就是与计算机交谈,所以编程的核心就是『准确地说出你的意思』。
2,利用重构来帮助理解不熟悉的代码,重构是理解软件设计的最快方式。
3,『我不是个伟大的程序员:我只是有着很多好习惯的优秀程序员而已』
4,事不过三,过则重构。
5,每次提交代码前都找人Code review。
6,间接层的价值:
允许逻辑共享(Pull up method, Pull up field)
分离“意图”与“实现”
封装变化
将条件逻辑加以编码( 多态)
7,哪怕你完全了解系统,也请使用性能测量工具来测试它的性能,不要臆测。(Benchmark)
第三章 代码的坏味道
1, Duplicated Code(重复的代码)
Extract Method, Pull up Method, Template Method模式
2, Long Method(过长函数)
Rename Method; Extract Method;
3, Large Class(过大类)
Extract Class; Extract SubClass; Extract Interface;
4, Long Parameter List(过长参数列表)
Replace Parameter With Method; Introduce Parameter Object
5, Divergent Change(发散式变化)
找出所有同一原因引起变化, 运用Extract Class将它们提炼到另一个Class 中
6, Shotgun Surgery(霰弹式修改)
运用Move Field, Move Method将所有需要修改的代码放进同一个类。
7, Feature Envy(依恋情结)
将总是一起变化的东西放一起。高内聚、低耦合。
8, Data Clumps(数据泥团)
Introduce Parameter Object; Preserve Whole Object
9, Primitive Obsession(基本类型偏执)
Replace Data Value with Object; Replace Type Code with Subclass; Replace Type code with State/Strategy
10, Switch Statements(switch语句)
多态; Replace Type Code with Subclass; Replace Type Code with State/Strategy; Replace Conditional with Polymorphism; Introduce Null Object
11, Parallel Inheritance Hierarchies(平行继承体系)
Move Method; Move Field
12, Lazy Class
Inline Class; Collapse Hierarchy
13, Speculative Generality(夸夸其谈未来性)
如果用不到, 就不要去做。
14, Temporary Field
Introduce Null Object
15, Message Chains(过度耦合的消息链)
16, Middle Man(中间转手人)
Remove Middle Man; Inline Method
17, Inappropriate Intimacy(狎昵关系)
高内聚、低耦合; Move Method; Move Field; Replace Inheritance with Delegation
18, Alternative Classes with Different Interfaces(异曲同工类)
Move Method; Extract Superclass
19, Incomplete Library Class(不完美的程序类库)
Introduce Foreign Method; Introduce Local Extension
20, Data Class(纯数据类)
Encapsulate Field
21, Refused Bequest(被拒绝的馈赠)
ush Down Method; Push Down Field
22, Comments(过多的注释)
Extract Method; Rename Method; Introduce Assertion
第四章 构筑测试体系
1,重构的前提是要有一套可靠的测试环境.(单元测试、回归测试、集成测试)
2,Class应该包含它们自己的测试代码.
确保所有测试都完全自动化,让它们自己检查测试结果。
3,频繁运行测试,极限编程XP。
5,使用工具。(IDE, JUnit, PowerMock…)
第五章 重构名录
1,介绍重构手法时采用的标准格式:
gt; 名称(name)
gt; 概要(summary)
gt; 动机(motivation)
gt; 做法(mechanics)
gt; 范例(examples)
2,重构技巧:小步前进,频繁测试。
第六章 重新组织你的函数
1,Extract Method(提取函数)
用函数的意图给它命名。
2,Inline Method,Inline Temp
去掉无用的间接层
3,Replace Temp with Query; Introduce Explaining Variable
4,Split Temporary Variable
一个变量只承担一个责任
5,Remove Assignments to Parameters(不要对函数参数赋值)
在pass by value传值方式中,对函数参数的任何修改,都不会对调用端产生任何影响。Java只使用pass by value.(函数指针)
6,Replace Method with Method Object
7,Substitute Algorithm(替换你的算法)
优先使用标准库(STL, Collection集合包, Apache Libs)
第七章 在对象间搬移特性
1,Move Method,Move Field
2,Extract Class,Inline Class
ingle Responsibility Principal
3,Hide Delegate,Remove Middle Man
4,Introduce Local Extension
运用subclass或是wrapper添加原始类的功能(Is-A, Has-A)
第八章 重新组织数据
1,Self Encapsulate Field(自封装值域)
get/set方法
2,Replace Data Value with Object(以对象取代数据值)
3,Change Value to Reference(将实值对象改为引用对象)
Change Reference to Value(将引用对象改为实值对象)
4,Replace Magic Number with Symbolic Constant
以有意义的符号常量取代magic number,提升可读性
5,Replace Type Code with Class(以类取代型别码)
Replace Type Code with State/Strategy(以State/Strategy取代型别码)
tate模式,Strategy模式,Factory Method模式
6,Replace Subclass with Fields(以值域取代子类)
创建子类的动机:添加新特性(field),改变行为(method)
第九章 简化表达式
1,Decompose Conditional 分解条件式
2,Consolidate Conditional Expression 合并条件式
Consolidate Duplicate Conditional Fragments 合并重复条件代码片段
3,Remove Control Flag
以break语句或return语句取代控制标记
4,Replace Nested Conditional with Guard Clauses 以卫语句取代嵌套表达式
卫语句要么从函数中返回,要么抛出一个异常
5,Replace Conditional with Polymorphism 以多态取代条件式
6,Introduce Null Object 引入Null对象
将null值替换为Null Object。Example:Collections.emptyList() ;
7,Introduce Assertion 引入断言
assert用来确认一定为真的先决条件
在交流上,断言帮助理解假设条件
在调试上,断言帮助找出bug
第十章 简化函数调用
1,Rename Method 重新命名函数
函数名称应准确表达意图。
2,Add Parameter 添加参数
Remove Parameter 移除参数
3,Separate Query fromModifier 将查询函数与修改函数相分离
一个函数只做一件事。Exception:使用cache提高查询速度
4,Parameterize Method 令函数携带参数
Replace Parameter with Explicit Methods 以明确函数取代参数
tringUtils.isEmpty(string); StringUtils.isNotEmpty(string);
5,Preserve Whole Object 保持对象完整
Introduce Parameter Object
6,Replace Parameter with Methods 以函数取代参数
7,Remove Setting Method;Hide Method
8,Replace Constructor with Factory Method 以工厂函数代替构造函数
Factory Method
9,Replace Error Code with Exception 以异常代替错误码
异常将程序正常逻辑与错误处理分开,使得程序更容易理解。unchecked异常、checked异常
10,Replace Exception with Test 以测试代替异常
异常只应用于意料错误之外的行为,不能替代成为条件检查
第十一章 处理概括关系
1,Pull Up Field 值域上移
ull Up Method 函数上移
ull Up Constructor Body 构造函数本体上移
ull Down Method 函数下移
ush Down Field 值域下移
2,Extract Subclass 提炼子类
ubclass只能表现一组变化,delegation委托可以表现不同变化
3,Extract Superclass 提炼超类
Template Method模式
4,Extract Interface 提炼接口
Java单继承多接口
5,Collapse Hierarchy 折叠继承体系
inline class
6,Replace Inheritance with Delegation 以委托代替继承Has-A
7,Replace Delegation with Inheritance 以继承取代委托Is-A