入职以来,被tuangou-goods折磨到不行,一直琢磨着要怎么重构它。因此在动大工之前,决定先恶补一下重构的理论知识。
于是,强烈推荐大家也读一读Martin Fowler大神的这本书。
***************我是分隔符,以下是我总结的干货***********************
一、什么是重构?
- 对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
二、为什么要重构?
- 重构改进软件设计
- 通过不断重构,可以发现并修改软件项目中不合理的地方,提升软件的设计,使软件始终处于一种可维护的状态
- 重构帮助找到bug
- 通过重构,可以发现软件中设计复杂和不合理的地方,往往代码逻辑特别复杂的地方就是bug常常产生的地方
- 重构提高编程速度
- 重构能提高代码质量,改善设计、提升可读性、减少错误
- 良好的设计维持开发速度的根本——重构可以帮助软件维持健康的状态
三、何时重构?
- 首先,不提倡专门划出时间和计划来重构,重构应该随时进行
- 当你多次做同样的事时(三次法则),你就应该重构
- 添加功能时重构:重构可以使项目更加易于添加新功能
- 修补错误时重构:bug产生的一大原因就是代码设计的不合理,而这往往意味着需要重构
- 复审代码时重构:Code Review能帮助项目知识的传播,当然也能在传播过程中暴露项目的问题(一个特殊的例子就是结对编程)
四、何时不重构?
- 项目实在是太烂,烂到开发一个新的都比重构快。。。
- 项目进度很紧,接近最后期限时
五、如何说服项目经理和产品经理项目需要重构?
咳咳。。。本文算不算
六、重构的基础
- 良好的测试环境和测试框架
- 重构建立在测试基础之上,由重构的定义可以看出,需要保持项目重构前后的可观察的外部逻辑行为不变
- 因此,每做一点重构之前,第一步就是测试覆盖
- 重构流程:测试一小点->重构一小点->测试一小点->重构一小点。。。循环往复,不断迭代
七、重构与性能
- 先通过重构写出可调的软件,再通过计量软甲测试系统性能,做到有针对性的优化。因此,重构可以提高系统的可优化性,间接提高系统性能。
七、什么样的代码需要重构?
- Duplicated Code(重复代码)
- Long Method(过长函数)
- 使用小函数能提高代码的解释能力、共享能力和选择能力;
- 现代的OO语言已经完全免除了进程内的函数调用开销——性能无忧
- 每当你觉得需要通过写注释来说明的时候,就是应该写一个独立函数的时候
- 良好的函数名能能够帮助理解
- 注释、条件表达式、循环、过多的内部变量 值得关注
- Large Class(过大的类)
- 过大的类意味着逻辑并没有良好的拆分
- 不利于代码的维护
- Long Parameter List(过长的参数列表)
- 太长的参数难以理解
- 太多的参数会造成前后不一致、不易使用
- Divergent Change(发散式变化)
- 当一个对象因为多种变化而修改时,就是发散式变化
- 一般来说,每个对象只应该因一种变化而需要修改
- Shotgun Surgery(霰弹式修改)
- 一个类受多种变化的影响
- 变化和修改应该是一一对应关系
- Feature Envy(依恋情结)
- 函数对某个类的兴趣高过对自己所处的类的兴趣
- 根本原则:总是将一起变化的东西放在一起
- Data Clumps(数据泥团)
- 两个类中相同的字段,函数签名里经常一起出现的相同参数
- 意即具有相关性的数据参数
- 需将这些具有极强相关性的数据提炼到一个类中
- Primitive Obsession(基本类型偏执)
- 大量的基本类型数据其实含有内在逻辑,无需偏执
- 可以将相关的组成对象,并赋予一定的逻辑
- Switch Statement(Switch语句)
- 有Switch的地方常常意味着这个地方可以使用多态
- 显然,多态更好维护,具有更好的扩展性
- Parallel Inheritance Hierarchies(平行继承关系)
- 当不同的继承体系之间实际上有内在关联性时
- 一般策略:让一个继承体系的实例引用另一个继承体系的实例
- Lazy Class(冗赘类)
- Speculative Generality(夸夸其谈未来性)
- 过度设计,代码中出现了所谓的“未来会用到的”代码
- 会造成系统难以维护和理解(一堆没用的代码写在那里,读的人肯定一头雾水的啊)
- Temporary Field(令人迷惑的临时字段)
- Message Chains(过度耦合的消息链)
- 用户向A请求B,再通过B请求C,然后很长。。。
- 意味着客户代码和查找过程中的导航结构紧密耦合
- Middle Man(中间人)
- Inappropriate Intimacy(狎昵关系)
- Alternative Classed with Different Interfaces(异曲同工的类)
- Incomplete Library Class(不完美的类库)
- Data Class(纯稚的数据类)
- Refused Bequest(被拒绝的遗赠)
- 子类通过继承体系拿到了它不愿拥有的成员变量和函数
- 此时证明继承体系的设计有问题
- Comments(过多的注释)
- 当需要一大堆注释来说明一个函数或字段时,那就说明了其复杂性
- 此时就需要合理的逻辑拆分和重构
***********我是干货的分隔符********************
具体的针对不同重构场景的重构技术,将在下一篇里总结。
持续学习中。。。
《重构——改善既有代码的设计》读书笔记(一)
原文:http://www.cnblogs.com/jingting/p/4998973.html