没有合适的资源?快使用搜索试试~ 我知道了~
首页重构 学习笔记 refactoring martin fowler
重构 学习笔记 refactoring martin fowler

前言 “每当我要进行重构的时候, 第一个步骤永远相同: 我得为即将修改的代码建立一组可靠的测试环境. 这些测试是必要的, 因为尽管遵循重构准则可以使我避免绝大多数的臭虫引入机会, 但我毕竟是人, 毕竟有可能犯错误. 所以我需要可靠的测试. ” 测试代码是重构的保证, 请确认重构是在测试代码的支持下完成的; 如果没有测试代码, 请在重构的时候加入测试代码 重构应当是小步, 有序的进行, 当某一小步失败时,应当确认能回退到上一步; 并从上一步开始重新重构, 而不是在错误的基础上进行调试;
资源详情
资源评论
资源推荐

前言
“每当我要进行重构的时候, 第一个步骤永远相同: 我得为即将修改的代码建立一组可靠的
测试环境. 这些测试是必要的, 因为尽管遵循重构准则可以使我避免绝大多数的臭虫引入机
会, 但我毕竟是人, 毕竟有可能犯错误. 所以我需要可靠的测试. ”
测试代码是重构的保证, 请确认重构是在测试代码的支持下完成的;
如果没有测试代码, 请在重构的时候加入测试代码
重构应当是小步, 有序的进行, 当某一小步失败时,应当确认能回退到上一步; 并从上一步开
始重新重构, 而不是在错误的基础上进行调试;
1 什么是重构
“所谓重构(refactoring)就是这样一个过程:在不改变代码外在行为的前提下,对代码做出修改,
以改进程序的内部结构.哪怕你手上有一个糟糕的设计,甚至是一堆混乱的代码,你也可以借
由重构把它加工成良好的代码.
“通过重构(refactoring),你可以找到改变的平衡点,你会发现所谓设计不再是一切动作的前提,
而是在整个开发过程中逐渐浮现出来的.在系统构筑过程中,你可以学习如何强化设计;期间
带来的互动性可以让一个程序在开发过程中持续保有良好的设计.”
2 重构原则
1 改进软件设计
“设计不良的程序往往需要更多代码, 这常常是因为代码在不同的地方使用完全相同的的语

句做同样的事情. 因此改进设计的一个重要方向就是消除重复代码(Duplicate Code), 这个动
作的重要性着眼于未来. 代码数量减少并不会使系统运行更快, 因为这对程序的运行轨迹几
乎没有任何明显的影响. 然而代码数量减少将使未来可能的程序修改动作容易的多 . 代码愈
多, 正确的修改就愈困难, 因为有更多的代码需要理解. 你在这儿做了点修改, 系统却不如预
期那样工作, 因为你未曾修改另一处---那儿的代码做着几乎完全一样的事情, 只是所处环境
略有不同,. 如果消除重复代码, 你就可以确定代码将所有事务和行为都只表述一次, 唯一次,
这正是优秀设计的根本;”
2 使软件更容易被理解
“如果他理解你的代码, 这个修改原本只需要一个小时”
“对代码做适当修改,让代码变得更容易理解”
很多时候那个”未来的开发者”就是我们自己;
“随着代码渐趋简洁, 我发现自己可以看到一些以前看不到的设计层面的东西;如果不对代码
做这些修改, 也许我永远看不见它们”
3 帮你找到臭虫
4 助你提高编程速度
“良好设计师快速软件开发的根本, 事实上拥有良好设计才可能达成快速的开发. 如果没有良
好的设计, 或许某一段时间内你的进展迅速, 但恶劣的设计很快就会让你的速度慢下来, 你会
把时间花在调试上面, 无法添加新功能. 修改时间愈来愈长, 因为你必须花愈来愈多的时间去
理解系统, 寻找重复代码,新特性需要更多代码才能实现
”

3 何时重构
三次法则
添加功能时一并重构
修补错误时一并重构
复审代码时一定重构
4 重构的难题
程序与数据库耦合
在程序和数据库之间增加分隔层
修改接口
修改已发布接口的时候要”留下旧函数,让它调用新函数”
不要过早发布接口
不要过多发布接口
难以通过设计手法完成的程序改动
选最简单的设计,哪怕他不能覆盖所有潜在需求

5 何时不该重构
“有时候既有代码实在太混乱. 重构它还不如重新写一个来的简单”
“现有代码根本不能正常运作”
“项目已近最后期限”
6 代码的坏味道
Duplicated Code(重复的代码)
根据重复的代码出现在不同的地方,分别采取不同的重构的策略:
在同一个 Class 的不同地方:通过采用重构工具提供的 Extract Method 功能提炼出重复的代
码, 然后在这些地方调用上述提炼出方法。
在不同 Subclasses 中:通过 Extract Method 提炼出重复的代码,然后通过 Pull Up Method 将
该方法移动到上级的 Super class 内。
在没有关系的 Classes 中:通过对其中一个使用 Extract Class 将重复的代码提炼到一个新类
中,然后在另一个 Class 中调用生成的新类,消除重复的代码。
Long Method(过长的函数)
过长的函数在我们的日常代码中经常可见
重构策略:通过 Extract Method 将过长的函数按照功能的不同进行适当拆解为小的函数,
并且给这些小函数一个好名字。通过名字来了解函数提供的功能,提高代码的理解性。
Large Class(过大的类)
过大的类也经常见到,特别是类中含有大量的成员变量。

重构策略:通过 Extract Class 将一些相关成员变量移植到新的 Class 中,如 Employee 类,
一般会包含有联系方式的相关属性(电话, Mobile,地址,Zip 等等),则可以将这些移
植到新的 EmployeeContact 类中。
Long Parameter List(过长参数列)
过长的参数列的主要问题是难以理解,并且难以维护。如果要增加新的参数或者删除某一
参数,易造成参数前后不一致。
重构策略:如果可以通过向已存在的对象查询获取参数,则可通过 Replace Parameter with
Method,移除参数列,通过在函数内部向上述已存在的对象查询来获取参数。
如果参数列中若干参数是已存在对象的属性,则可通过 Preserve Whole Object 将这些参赛
替换为一个完整对象,这样不仅提高代码的可读性,同时已易于代码今后的维护。
另外,还可以将若干不相关的参数,使用 Introduce Parameter Object 来创建一个新的参数类。
不过,我个人觉得如果这些情况过多的话,会产生很多莫名其妙的参数类了,反而降低代
码的可读性。
Divergent Class(发散式变化)
现象:当某个 Class 因为外部条件的变化或者客户提出新的功能要求等时,每次修改要求
我们更新 Class 中不同的方法。不过这种情况只有在事后才能觉察到,因为修改都是在事
后发生的么(废话)。
重构策略:将每次因同一条件变化,而需要同时修改的若干方法通过 Extract Class 将它们
提炼到一个新 Class 中。实现目标是:每次变化需要修改的方法都在单一的 Class 中,并且
这个新的 Class 内所有的方法都应该与这个变化相关。
Shotgun Surgery(霰弹式修改)
现象:当外部条件发生变化时,每次需要修改多个 Class 来适应这些变化,影响到很多地
方。就像霰弹一样,发散到多个地方。
重构策略:使用 Move Method 和 Move Field 将 Class 中需要修改的方法及成员变量移植到
同一个 Class 中。如果没有合适的 Class,则创建一个新 Class。实现目标是,将需要修改的
地方集中到一个 Class 中进行处理。
剩余31页未读,继续阅读
















安全验证
文档复制为VIP权益,开通VIP直接复制

评论1