学习重构(1)-代码的坏味道
前言:最近做一个特性,参照原有逻辑增加某个功能,老代码本身存在两套相似的流程,再添加上一套流程后,发现代码的重复度及其的高,基本可以理解为一套框架流程复制出来3个类,给3个功能使用。我对比了每个类的代码后,发现代码重复度基本在50%以上,这种代码真是越写越烂的感觉。于是费力的做了一下重构,搞了个父类出来,抽取了大部分公共函数,整体代码看着就舒服多了。草草做了下重构后,突然觉得自己并不系统的知道要如何重构,只是知道些皮毛,又自我感觉良好的样子。翻出很久都没电的kindle,本想买本重构的书看,突然记起找了下尘封已久的《重构 改善既有代码的设计》,再次拜读一遍吧,希望能形成一套重构的方法论。
重构:对软件内部结构的一种调整,目的是再不改变软件可观察行为的前提下,提高其可理解性,降低修改成本。
为何重构:重构改进软件设计;重构使软件更容易理解;重构帮助找到bug;重构提高编程速度。
何时重构:书里提到了“三次法则”:第一次做某件事时只管去做;第二次做类似的事会产生反感,但无论如何还是可以去做;第三次再做类似的事,你就应该重构。事不过三,三则重构。添加功能时重构,修补错误时重构,复审代码时重构。
Duplicated Code(重复代码)
Long Method(过长函数)
Large Class(过大的类)
Long Parameter List(过长参数列)
Divergent Change(发散式变化) 某个类因为不同的原因在不同的方向上发生变化,比如切换数据库类型,引起了修改多个函数来适配。
Shotgun Surgery(霰弹式修改) 每遇到某种变化,需要在许多不同的类内做许多小修改。
Feature Envy(依恋情结) 函数对某个类的兴趣高过了对自己所处类的兴趣,最通常遇到的就是数据类,比如某个函数访问大部分数据类的数据。
Data Clumps(数据泥团) 常常在很多地方看到相同的三四项数据,比如两个类中相同的字段,许多函数签名中相同的参数。
Primitive Obsession(基本类型偏执) 如果你有一组应该总是被放在一起的字段,那么就不要固执的使用基本类型,使用对象。
Switch Statements(switch惊悚现身) 少用switch语句,这个语法的问题就是重复。
Parallel Inheritance Hierarchies(平行继承体系) 某个继承体系的类名称前缀和另一个继承体系的类名称前缀完全相同。
Lazy Class(冗赘类) 随着时间和代码的演进,某个类逐渐失去了存在的价值。
Speulative Generality(夸夸其谈未来性) 在还不需要的时候就按照未来可能会用到,会扩展的想法来写,比如抽象。
Temporary Field(令人迷惑的暂时字段) 其内某个实例变量仅为某种特定情况而设。
Message Chains(过度耦合的消息链) 对象1向对象2请求对象3,再向对象3请求对象4,再向对象4请求对象5,这就是消息链。
Middle Man(中间人) 某个类接口有一半的函数都委托给其他类。
Inappropriate Intimacy(狎昵关系) 两个类过于亲密,过于关心彼此的private成分。
Alternative Classes with Different Interfaces(异曲同工的类) 两个函数做同一件事,却有着不同的签名。
Incomplete Library Class(不完美的库类)
Data Class(纯数据类) 数据类必然会被其他类过分细琐的操控着。
Refused Bequest(被决绝的遗赠) 子类复用了超类的实现,却又不愿意支持超类的接口。
Comments(过多的注释)