重构改善既有的代码设计(重构原则 )

重构:对软件内部结构的一种调整,目的是再不改变软件的可观察行为的前提下,提高其可理解性,降低其修改成本。


两顶帽子

添加新功能 添加新功能时不应该修改既有代码,只管添加新功能,通过测试
重构 重构时你就不能再添加功能,只管改进程序结构,此时你不应该添加任何测试,只在绝对必要(用以处理接口变化)时才修改测试

为何重构

  • 重构改进软件设计
  • 重构使软件更容易理解[1]
  • 重构帮助找到bug
  • 重构提高编程速度[2]

何时重构

  • 三次法则
    • 第一次做某件事时只管去做;第二次做类似的事会产生反感第三次再做类似的事,你就应该重构。(事不过三,三则重构)
  • 添加功能时重构
  • 修补错误时重构

重构的难题

  • 数据库重构
  • 修改接口
    • 让旧接口调用新接口,当你要修改某个函数的名称时请留下旧函数,让它调用新函数 。千万不要复制函数实现,那会让你陷入重复代码的泥淖中难以自拔。你还应该使用java中depreciation注解,将旧接口标记为@deprecated
  • 难以通过重构手法完成设计的改动
    • 先想像重构的情况。考虑选设计方案时,我会问自己:将某个设计重构为另一个设计的难度又多大?看上去很简单,我就不必太担心选择是否得当,于是我就会选择最简单的设计,哪怕他不能覆盖所有潜在的需求也没关系,但如果预先看不到简单的重构办法,我就会在设计上投入更多的力气。
  • 何时不该重构
    现有代码根本不能正常运作。重构之前,代码必须起码能够在大部分情况下正常运作 如果项目已近最后的期限,你也应该避免重构,如果项目已经非常接近最后期限,你不应该再分心于重构,因为已经没有时间了。重构能够提高生产力如果最后你没有足够时间,通常就表示你其实早该进行重构。

重构与设计

  • 如果选择重构,问题的重点就改变了,你仍然做预先设计,但是不必一定找出正确的解决方案,此刻的你只需要得到一个足够合理的解决方案就够了。
  • 有了重构,你就可以通过一条不同的途径来应付变化带来的风险。你仍旧需要思考潜在的变化,仍旧需要考虑灵活的解决方案。但是你不必再主意实现这些解决方案而是应该问问自己:"把一个简单的解决方案重构成这个灵活的方案又多大难度?"如果答案是“相当容易”,那么就只需要实现目前的简单方案就行了。

间接层和重构(间接层的价值)

  • 允许逻辑共享
    • 比如说一个子函数再两个不同的地点被调用,或超类中的某个函数被所有子类共享
  • 分开解释意图和实现
    • 你可以选择每个类和函数的名字,这给你一个解释自己意图的机会。类或函数内部则解释实现了这个意图的做法。如果类和函数内部又以更小单元的意图来编写,你所写的代码就可以描述其结构中的大部分重要信息
  • 隔离变化
    • 很可能我在两个不同的地点使用同一对象,其中一个地点我想改变对象行为,但如果修改了它,我就要冒同时影响两处的风险。为此我做出一个子类,并在需要修改出引用这个子类。现在,我可以修改这个子类而不必承担午一中影响另一处的风险。
  • 封装条件逻辑
    • 对象有一种奇妙的消息机制:多态消息,可以灵活而清晰地表达条件逻辑。将条件逻辑转化为消息形式,往往能降低代码的重复,增加清晰度并提高弹性。

  1. 什么是难以理解的程序
    难以阅读的程序,难以修改
    逻辑重复的程序,难以修改
    添加新行为时需要修改已有的代码的程序难以修改带
    复杂条件逻辑的程序,难以修改 ↩︎

  2. 我们希望程序
    容易阅读
    所有逻辑都旨在唯一地点指定
    新的改动不会危机现有行为
    尽可能简单表达条件逻辑 ↩︎

posted @ 2018-11-27 18:43  Ccaveman  阅读(1016)  评论(0编辑  收藏  举报