在不改变软件可观察行为的前提下,对软件内部结构的一种调整,提升其可理解性,下降修改为本。git
测试、小修改、测试、小修改......正是这种节奏让重构得以快速安全而安全的前行。程序员
若是想要重构,咱们必须拥有一个良好的测试环境。编写优良的测试程序,能够极大的提高编程速度和代码质量,即便不进行重构也同样如此。github
每当咱们收到一个bug报告时,请先写一个单元测试来暴露bug。编程
测试是一种风险驱动的行为,测试的目的是但愿找出如今或将来才可能出现的错误。 测试的要诀是:测试你最担忧出错的部分。这样你就能从测试工做中获得最大的利益。缓存
“花费合理的时间找出大多数的bug”好过“穷尽一辈子抓出全部bug”。安全
重复代码 重复代码应该考虑将其提炼到一个独立的函数或类中。框架
过长函数 当咱们看见一个过长的函数或者须要一段注释才能让人理解其用途的代码时,咱们就须要将这段代码放到一个独立的函数中。 一个函数多长才算合适?在我看来长度不是问题,关键在于函数名称和函数体之间的语义距离。若是提炼能够强化代码清晰度,那就去作,就算函数名称比提炼出来的代码还要长也无所谓。函数
内联函数 有时候会遇到某些函数,其内部代码和函数名称一样清晰易读,咱们就能够去掉这个函数直接使用其中代码。工具
内联临时变量 若是发现一个临时变量只被一个简单表示式赋值一次,而且妨碍了其余重构手法,咱们就应该让他内联化。 直接将变量声明成final的,能够检查变量是否真的是被赋值了一次。性能
以查询来取代临时变量
引入解释性临时变量 将复杂表达式的结果放到一个临时变量,以变量名称来解释表达式用途。
分解临时变量
在对象设计过程当中,决定把“责任”放在哪里是很是总要的。这曾经让我很是苦恼,可是如今我知道,在这种状况下,能够运用重构,改变原有的设计。
搬移函数 “搬移函数”是重构理论的支柱。若是一个类有太多行为,若是一个类和另外一个类高度耦合,咱们就须要搬移函数。
搬移新的字段 随着系统的发展,你会发现本身须要新的类,并将现有的工做拖到新的类中。若是发现对于一个字段,在其所驻类以外的另外一个类中都有更多函数使用了它,我就会考虑搬移这个字段。
提炼类 一个类应该是一个清晰的抽象,处理一些明确的责任。
能够将一个复杂的条件逻辑分解成若干小块。这样可使得分支逻辑和操做细节分离。
分解条件表达式 分解表达式能够突出条件逻辑,更清晰地代表每一个分支的做用,并突出每一个分支的缘由。 作法:将分支语句提炼出来,构成一个独立的函数。
合并表达式 有时会发现一串的表达式检查条件各不相同,但最终行为却一致。若是这样就须要使用“逻辑与”或“逻辑或”合并表达式。
合并重复的条件片断 当全部分支都会执行相同代码时,就须要将这段代码搬移到条件表达式以外了。这样咱们能更加清晰的知道,那些东西是随着条件变化而变化的、那些是不变的。
移除控制标记 控制标记可使用break或continue来代替,还可使用return直接返回。
以卫语句来取代嵌套表达式 可让代码逻辑看起来更加的清晰。
以多态来取代条件表达式 多态的好处在于:若是你须要根据对象的不一样类型来采起不一样的行为,多态使你没必要写明显的条件表达式。
- 改函数名 函数的名称应该准确的表达它的用途。给函数命名有一个好的办法:首先考虑应该给函数写上一句这样的注释,而后在想办法将注释变成函数名称。
移除参数 参数表明着函数所需的信息,不一样的参数值有不一样的意义。若是不去掉多余的参数,就会让每一位调用者多费一份心。
将查询函数和修改函数分离 任何有返回值的函数,都不因该有看到的反作用。
引入参数对象 为了缩短参数列,咱们可使用一个对象来包装全部的参数。这样能够下降理解和修改函数代码的难度。
以异常来取代错误码 若是调用者有责任在调用前检查必要状态,就抛出非受控异常。
划分边界 肯定各个字段、方法应该处于子类仍是超类也是咱们常常须要注意的一个点。
提炼子类、超类和接口
折叠继承体系 有时咱们会发现某个子类并无带来该有的价值时,咱们就须要将子类的超类合并。
塑造模板函数 你有一些子类,其中相应的某些函数以相同顺序执行相似的操做,可是各个操做细节上有所不一样。将这些操做分别放进独立函数中,并保证他们有相同的签名,因而原函数也变得相同了,而后将原函数移至超类。
以委托取代继承 当某个子类只使用接口中的一部分,或者不使用继承而来的数据时,咱们能够在子类新建一个字段用以保存超类:调整子类函数,令他改而委托超类;而后去掉二者间的继承关系。
《重构改善既有代码设计》
为监控而生的多级缓存框架 layering-cache这是我开源的一个多级缓存框架的实现,若是有兴趣能够看一下