重构-改善既有的代码设计(一)

来源:互联网 发布:淘宝男鞋 编辑:程序博客网 时间:2024/05/22 14:16

重构原则

1. 重构的定义

名词形式的定义:
对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。
动词形式的定义:
使用一系列重构手法,在不改变软件可观察行为的前提下,调整期结构。

2. 代码的坏味道

2.1 Duplicated Code(重复代码)

如果在一个以上的地点看到相同的程序结构,那么可以肯定,设法将他们合二为一,程序会变得更好。

2.2 Long Method(过长的函数)

每当感觉需要以注释来说明点什么的时候,我们就把需要说明的东西写进一个独立的函数中,并以其用途命名。

2.3 Large Class(过大的类)

和“太多实例变量”一样,类内如果有太多代码,也是代码重复、混乱并最终走向死亡的源头。

2.4 Long Parameter List(过长参数列)

如果向已有的对象发出一条请求就可以替代一个参数,那么你就该激活重构手法Replace Parameter with Method.因为太长的参数列难以理解,太多的参数会造成前后不一致,不易使用,而且一旦你需要更多数据,就不得不修改它。

2.5 Divergent Change(发散式变化)

如果某个类经常因为不同的原因在不同的方向上发生变化,Divergent Change就出现了。最好每个对象可以只因一种变化而需要修改。针对某一外界变化的所有响应修改,都只应该发生在单一类中。

2.6 Shotgun Surgery(霰弹式修改)

如果每遇到某种变化,你都必须在许多不同的类内作出许多小修改,你所面临的就是Shotgun Surgery。这种情况你应该讲所有需要修改的代码放进同一个类中。
Divergent Change是指“一个类受多种变化的影响”,Shotgun Surgery是“一种变化引发多个类相应修改”。

2.7 Feature Envy(依恋情结)

如果一个类中的某个函数为了计算某个值,从另一个对象那调用几乎半打的取值函数。那么,把这个函数移到另一个地方,往往是移到它使用数据最多的那个类中。

2.8 Data Clumps(数据泥团)

你常常可以在许多地方看到相同的三四项数据:两个类中相同的字段、许多函数签名中相同的参数。这些总是绑在一起出现的数据应该属于它们自己的对象。

2.9 Primitive Obsession(基本类型偏执)

你可以在某些环境下将基本类型数据换为对象,比如讲单独存在的数据值替换为对象,将一组总是被放在一起的字段换为对象,如果你从数组中挑选数据,可运用Replace Array with Object。

2.10 Switch Statements(switch惊悚现身)

面向对象程序的一个最明显的特征就是少用switch语句。从本质上说,switch语句的问题在于重复。你常会发现同样的switch语句散步于不同地点。你应该考虑以多态来替换,当然有些情况下你只需要将switch放在一个独立函数中就可以了,因为使用多态有点大材小用。

2.11 Parallel Inheritance Hierarchies(平行继承体系)

Parallel Inheritance Hierarchies其实是Shotgun Surgery的特殊情况。在这种情况下,每当你为某个类增加一个子类,必须也为另一个类响应的增加一个子类。如果你发现某个继承体系的类名称前缀和另外一个继承体系的类名称前缀完全相同,这是你需要重构。一般策略是:让一个继承体系的实例引用另一个继承体系的实例。

2.12 Lazy Class(冗赘类)

如果一个类的所得不值其身价,它就应该消失,因为每个类都得有人去理解它,维护它,所有这些工作都是需要花钱的。

2.13 Speculative Generality(夸夸其谈未来性)

当有人说“我想我们总有一天需要做这事”,并因而企图以各种各样的钩子和特殊情况来处理一些非必要的事情,这就是夸夸其谈未来性。

2.14 Temporary Field(令人迷惑的暂时字段)

某些类的一些字段只在某些情况下才会被对象所使用,这时候你应该给这些变量创建一个家,并把和这些变量相关的代码也放进去。

2.15 Message Chains(过度耦合的消息链)

如果你看到用户向一个对象请求另一个对象,然后再向后者请求另一个对象,然后再请求另一个对象……这就是消息链。

2.16 Middle Man(中间人)

如果你过度运用委托,你也许可以看到某个类接口有一半的函数都委托给其他类,这就是过度运用。

2.17 Inappropriate Intimacy(狎昵关系)

如果两个类对彼此private成分的调用过于“密切”,这时候你就需要重构。

2.18 Alternative Classes with Different Interfaces(异曲同工的类)

如果两个函数做同一件事,却有着不同的签名。

2.19 Incomplete Library Class(不完美的库类)

库往往构造的不够好。

2.20 Data Class(纯稚的数据类)

比如实体类,应该将其字段全部封装,对外只提供访问这些字段的函数。

2.21 Refused Bequest(被拒绝的遗赠)

子类应该继承超类的函数和数据,但如果他们不想或不需要被继承,该怎么办?传统做法是为子类建立兄弟类,将用不到的函数下推给兄弟类。

2.22 Comments(过多的注释)

当你感觉需要撰写注释时,请先尝试重构,试着让所有注释都变得多余。比如修改代码,提炼代码或者修改函数名,用函数名来表达函数要干什么。

本文引用自图灵程序设计丛书:重构 改善改善既有的代码设计。

0 0
原创粉丝点击