1. Self Encapsulate Field 自封装字段
为字段建立Setter/Getter,并且只以这些函数来访问字段
做法:
为待封装字段建立取值/设置函数
找出该字段的所有引用点,将他们全部改为调用取值/设值函数
将该字段声明为private
复查,确保找出所有引用点
编译测试
2. Replace Data Value with Object 以对象取代数据值
有一个数据项,需要与其他数据和行为一起使用才有意义
做法:
为待替换数值新建一个类,在其中声明一个final字段,其类型和源类中的待替换数值类型一样,然后在新类中加入这个字段的取值函数,再加上一个接受此字段为参数的构造函数
编译
将源类中的待替换数值字段的类型改为前面新建的类
修改源类中该字段的取值函数,令它调用新类的取值函数
如果源类构造函数中用到这个待替换字段(多半是赋值动作),我们就修改构造函数,令它改用新类的构造函数来对字段进行赋值动作
修改源类中待替换字段的设置函数,令它为新类创建一个实例
编译测试
现在,你有可能需要新类使用Change Value to Refrence
3. Change Value to Reference 将值对象改为引用对象
从一个类衍生出许多彼此相等的实例,比如同样表示2010-1-1的日期对象,希望将他们替换为同一个对象
做法:
使用 Replace Constructor with Factory Method
编译测试
决定由什么对象负责提供访问新对象的途径,可能是一个静态字典或一个注册表对象
决定这些引用对象应该预先创建好,或是应该动态创建
修改工厂函数,令它返回引用对象
4. Change Reference to Value
有一个引用对象,很小且不可变,而且不易管理。这里有必要澄清一下“不可变”的意思。如果以Money类表示钱的概念,其中有“币种”和“金额”两条信息,那么Money对象通常是一个不可变的值对象。这并非意味你的薪资不能改变,而是意味:如果要改变你的薪资,就需要使用另一个Money对象来取代现有的Money对象,而不是在现有的Money对象上修改。
做法:
检查重构目标是否为不可变对象,或是否可修改为不可变对象
建立equals() 和 hashCode()
编译测试
考虑是否可以删除工厂函数,并将构造函数声明为public
5. Replace Array with Object 以对象取代数组
有一个数组,其中的元素各自代表不同的东西。以对象替换数组,对于数组中的每个元素,以一个字段来表示
String [] row = new String[3];
row[0] = "Liverpool";
row[1] = "15";
Performance row = new Performance();
row.setName("Liverpool");
row.setWins("15");
做法:
新建一个类表示数组所拥有的信息,并在其中以一个 public 字段保存原先的数组
修改数组的所有用户,让他们改用新类的实例
编译测试
逐一为数组元素添加Setter/Getter函数。根据元素的用途,为这些访问函数命名。修改客户端代码,让他们通过访问函数取用数组内的元素,每次修改后,编译并测试。
当所有对数组的直接访问都转而调用访问函数后,将新类中保存该数组的字段声明为private
编译
对于数组内的每一个元素,在新类中创建一个类型相当的字段。修改该元素的访问函数,令它改用上述的新建字段。
每修改一个元素,编译并测试
数组的所有元素都有了相应字段之后,删除该数组
6. Duplicate Observed Data 复制”被监视数据“
一些领域数据置身于GUI控件中,而领域函数需要访问这些数据,将该数据复制到一个领域对象中,建立一个Observer模式,用以同步领域对象和GUI对象内的重复数据。
该例比较复杂,请参考书内描述
7. Change Unidirectional Association to Bidirectional 将单向关联改为双向关联
两个类都需要使用对方特性,但其间只有一条单向连接。添加一个反向指针,并使修改函数能够同时更新两条连接
做法:
在被应用类中增加一个字段,用以保存反向指针
决定由哪个类——引用端还是被引用端——控制关联关系。如果是”一对多“关系,那么就由”拥有单一引用“的哪一方承担”控制者“角色。
在被控端建立一个辅助函数,其命名应该清楚指出它的有限用途
如果既有的修改函数在控制端,让它负责更新反向指针
如果既有的修改函数在被控端,就在控制端建立一个控制函数,并让既有的修改函数调用这个新建的控制函数。
8. Change Bidirectional Association to Unidirectional 将双向关联改为单向关联
去除不必要的关联
做法:
找出保存”你想去除的指针“的字段,检查它的每一个用户,判断是否可以去除该指针
如果客户使用了取值函数,先运用 Self Encapsulate Field 将待删除字段自我封装起来,然后使用 Substitute Algorithm 对付取值函数,令它不再使用该字段,然后编译测试。
如果客户并未使用取值函数,那就直接修改待删除字段的所有被引用点:改以其他途径获得该字段所保存的对象。每次修改后,编译并测试
如果已经没有热河函数使用待删除字段,移除所有对该字段的更新逻辑,然后移除该字段。
编译测试
9. Replace Magic Number with Symbolic Constant 以字面常量取代魔法数
创建一个常量,根据其意义为它命名,并将上述的字面数值替换为这个常量
10. Encapsulate Field 封装字段
类中存在一个public 字段,将它声明为private,并提供相应的访问函数。
11. Encapsulate Collection 封装集合
让这个函数该集合的一个只读副本,并在这个类中提供添加/移除集合元素的函数。
做法:
加入为集合添加/移除元素的函数
将保存集合的字段初始化为一个空集合
编译
找出集合设值函数的所有调用者。你可以修改那个设值函数,让它使用上述新建立的”添加/移除元素“函数;也可以直接修改调用端,改让他们调用上述新建立的”添加、移除元素“函数。
编译测试
找出所有”通过取值函数获得集合并修改其内容“的函数,逐一修改这些函数,让他们改用添加、移除函数。每次修改后,编译并测试
修改完上述所有”通过取值函数获得集合并修改集合内容“的函数后,修改取值函数自身,使它返回该集合的一个只读副本。使用Collection.unmodifiableXxxx()得到该集合的只读副本。
编译测试
找出取值函数的所有用户,从中找出应该存在于集合所属对象内的代码,运用Extract Method和Move Method将这些代码移到宿主对象去
分享到:
相关推荐
[免费高清PDF]31天重构系列笔记.rar [免费高清PDF]31天重构系列笔记.rar
31天重构学习笔记中文汉化版,非常好的编程规范书籍
《重构商业:产业互联网时代的商业模式重构》读书笔记模板.pptx
“每当我要进行重构的时候, 第一个步骤永远相同: 我得为即将修改的代码建立一组可靠的测试环境. 这些测试是必要的, 因为尽管遵循重构准则可以使我避免绝大多数的臭虫引入机会, 但我毕竟是人, 毕竟有可能犯错误. ...
如何改善代码的设计-读《重构》读书笔记.pdf
正文:在很多时候,我们都不希望把一些不必要的操作暴露给调用端,只需要给它所需要的操作或数据就行,那么做法就是封装。这个重构在微软的代码库也经常遇到。比如最经典的属性对字段的封装就是一个很好的例子,那么...
1. 神秘命名(Mysterious Name) 2. 重复代码(Duplicated Code) 3. 过长函数(Long Function)关键在于“做什么
个人读书笔记,学习共享,希望每个苦恼于代码一坨坨混乱不堪的程序员都能学习. * 整洁代码的意义? 可读性,可维护性。 * 如何写出整洁代码? 1.只做一件事 2.不重复 3.有表达力 * 整洁代码的态度要求,要遵守...
根据《重构 改善既有代码结构》一书,摘录重点整理分析得出的一个PPT,希望对大家有点帮助
重构是持续改进代码的基础。抵制重构将带来技术麻烦:忘记代码片段的功能、创建无法测试的代码等等。 而有了重构,使用单元测试、共享代码以及更可靠的无 bug 的代码这些最佳实践就显得简单多了。
重构不是一项靠着天分挥洒的艺术,而是一项工程。重构是一种有纪律的,经过训练的,有条不紊的程序整理方案,可以将整理过程中不小心引入错误的机率降到最低
重构 改善既有代码的设计笔记 网络转载,分享快乐
关于如何重构java代码的。看过好一定很有感触。
【美】马丁福勒 著 是国际著名的面向对象分析设计、UML、模式等方面的专家,敏捷开发方法的创始人之一 重构_改善既有代码设计 软件工程领域的超级经典巨著,与另一巨著《设计模式》并称"软工双雄
第5章 重构列表5.1 重构的记录格式每个重构方法都有如下五个部分:概要(summary)简单介绍此重构方法的适用情景,以及它所做的事情。动机(motivati
NULL 博文链接:https://jianzong2000.iteye.com/blog/1668363
NULL 博文链接:https://aqxiebin.iteye.com/blog/1579688
跟着七月老师学flask第二天的笔记,详细截图说明了代码重构过程,对flask 有新的认识
重构:改善既有代码的设计(第2版)学习笔记