一、什么是重构
重构:在不改变软件可观察行为的前提下改善其内部结构。提高可理解性,降低修改成本
懒惰是程序员的美德之一
懒惰:它使得你花大力气去避免消耗过多的精力。它敦促你写出节省体力的程序,同时别人也能利用它们。为此你会写出完善的文档,以免别人问你太多问题。
急躁:当你发现计算机懒洋洋地不给出结果。于是你写出更优秀的代码,能尽快真正的解决问题。至少看上去是这样。
傲慢:极度的自信,使你有信心写出(或维护)别人挑不出毛病的程序。
二、何时重构
如果你发现自己需要加入一个新特性,而代码结构使你无法很方便地达成目的,那就先重构,然后再添加特性
唯有写出人类容易理解的代码,才是优秀的程序员
先写程序,写完之后再考虑性能
重构步骤:先写测试,小步修改
何时重构:
重构应该随时随地进行
事不过三,三则重构
添加功能时重构
修补错误时重构
复审代码时重构
一个好的程序应该:
容易阅读
所有逻辑都只在唯一指定地点指定
新的改动不会危及现有行为
尽可能的简单表达条件逻辑
三、什么样的应该重构
坏味道:
名称 |
描述 |
解决方案 |
重复代码 |
如题 |
提取函数 |
过长函数 |
如题 |
提取函数,一个函数只做一件事,在同一抽象层级,20行以内 |
过大的类 |
如题 |
提取类,一个类只应该有一个被修改的理由 |
过长参数列表 |
如题 |
最好没有,最多三个 |
发散式变化 |
一个类有多个修改理由 |
提取类,一个类只应该有一个被修改的理由 |
霰弹式修改 |
一个变化需要修改多处 |
把需要改动的部分移到同一处 |
依恋情结 |
函数对某个类的兴趣高过对自己所处类的兴趣 |
移动方法 |
数据泥团 |
一段数据重复出现多次 |
移到一个对象中 |
基本类型偏执 |
不愿在小任务上使用小对象 |
用小对象代替一段基本数据类型 |
switch |
如题 |
用多态代替switch |
平行继承体系 |
每当你为某个类增加一个子类,也必须为另外一个类增加一个子类 |
让一个继承体系的实例引用另一个继承体系的实例 |
冗赘类 |
几乎没用的组件 |
合并该类至另一个类中 |
夸夸其谈未来性 |
想做但还没做的类或函数 |
如果用到就做,如果用不到就不做 |
令人迷惑的临时字段 |
类中的某个实例变量仅为某种特殊情况而设 |
将这个临时变量提取到一个类中 |
过度耦合的消息链 |
消息链过长 |
运用委托,直接获取最终项 |
中间人 |
某个类接口有一半的函数都委托给其他类 |
直接获取委托中的类 |
亲密关系 |
两个类过于亲密,花太多时间去探究彼此的private成分 |
划清界限 |
相同的类,不同的接口 |
两个函数做同一件事,却有着不同的签名(实现) |
重命名,抽象子类 |
不完整的类库 |
原有类库的服务不能满足要求 |
外层包装函数 |
数据类 |
只有数据,没有操作的类 |
减少public,移动操作函数至该类中 |
拒绝遗赠 |
子类复用超类的行为,却不愿支持超类的接口 |
使用委托 |
过多的注释 |
如题 |
用好名字代替注释 |