第三章 代码的坏味道
优秀的程序员,就像一名猎人,穿梭在茂密的丛林中,寻找着一闪而过的猎物。精准、高效、灵敏,这是生存的法则,我们,作为猎人,绝不能被困住,我们要解决它们。
没有任何量度规矩比得上一个见识广博者的直觉。我们只会告诉你一些迹象,它会指出“这里有一个可以用重构解决的问题”。你必须培养出自己的判断力,学会判断一个类内有多少实例变量算是太大、一个函数内有多少行代码才算太长。
3.1 重复代码(Duplicated Code)
重复代码的表现形式:
- 同一个类中两个方法含有相同的表达式。
- 两个互为兄弟的子类内含相同表达式
当重复代码出现时,我们常用的重构方法有:提炼函数、函数上移、塑造模板函数、替换算法、提炼类,以下将分别介绍。
-
提炼函数(6.1 Extract Method):把重复的部分拿出来组成一个方法。
-
函数上移(11.2 Pull Up Method):这是学到现在为止的又一个新重构方法,在此简单介绍。
函数上移(11.2 Pull Up Method):一个父类下的多个子类的某个方法几乎完全相同,就应该把这个方法移动到父类中去。
- 塑造模板函数(11.10 From Template Method):完全重复的代码用不着这种重构方法,这种方法适合用在代码类似,并非完全相同,只是步骤相同的情况下。
塑造模板函数(11.10 From Template Method):当子类中存在的某个方法,大致内容相同,仅仅存在几个操作的细节不同,那么我们就应该考虑,将函数上移的同时,把不同操作细节用抽象方法进行封装,在父类中形成一个模板函数去调用这些抽象方法。
在设计模式中有一种模板方法模式。
模板方法模式:当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。通过模板方法模式,将不变的行为作为一个方法放在父类中,把可变的行为作为抽象方法,在方法中调用抽象方法,这样就能帮助子类摆脱重复的不变行为的纠缠。
有关设计模式的简单介绍,我参照了《大话设计模式》这本书。
这本书写得通俗易懂,适合科普。
- 替换算法(6.9 Substitute Algorithm):如果有些函数以不同的算法做相同的事(不同的行为,相同的功能,也是重复),你可以选择其中较清晰的一个,并使用这重构方法,将其他函数的算法替换掉。
替换算法(6.9 Substitute Algorithm):用简单的算法替换复杂、或者用高效的算法替换低效。理解起来很容易,做起来需要经验。
- 提炼类(7.3 Extract Class):如果两个毫不相关的类出现重复代码,就应该考虑这种重构方法,将重复代码提炼到一个独立类中,然后在另一个类内使用这个新类。
提炼类(7.3 Extract Class):如果你发现,某几端代码,连同某几个字段,总会同时出现在一起,用于实现某个功能,那么,请考虑把字段、方法提炼到一个类中,不仅仅是避免了重复,而且满足了单一职责。