转自: http://www.cnblogs.com/rickie/archive/2004/11/08/61311.html
动了情的至尊宝在那个月圆之夜有感而发:长夜漫漫,无心睡眠。从此,他的夜生活变得多姿多彩起来。唉,我以为只有至尊宝才有这等幸运。
想起放在抽屉的《重构》,遂拜读大师的作品来催眠,度过一个无心睡眠的漫漫长夜。
……
本文继续重构(
Refactoring
)技巧读书笔记系列。重构虽然是对现有的代码进行设计,以提高代码的质量和灵活性,但实际上,如果软件工程师掌握重构技术,对其初期的软件设计也有很好的指导,减少不当设计或设计不足,减少代码坏味道
(
Bad Smell in Codes
),构建良好的系统。
注:本文重构策略的名称及其大部分内容来自《重构-改善既有代码的设计》一书,
Martin Fowler
著,侯捷等译。
一、代码坏味道(
Bad Smell in Codes
)及其重构策略
11
.
Parallel Inheritance Hierarchies
(平行继承体系)
现象:为某个
class
增加一个
subclass
时,也必须为另一个
class
相应增加一个
subclass
。重构策略:
在一个
class
继承体系的对象中引用(
refer to
)另一个
class
继承体系的对象,然后运用
Move Method
和
Move Field
将被引用
class
中的一些方法和成员变量迁移宿主
class
中,消除被引用
class
的继承体系(注:这种平行继承体系好象比较少见也)。
12
.
Lazy Class
(冗赘类)
现象:某一些
class
由于种种原因,现在已经不再承担足够责任,有些多余了。如同国有企业冗余人员一样,需要下岗了。
重构策略:通过
Collapse Hierarchy
,将这些冗余的
class
合并到
superclass
或
subclass
中,或者通过
Inline Class
(与
Extract Class
相反),将这些冗余
class
中的所有
Method/Field
迁移到其他相关的
class
中。
13
.
Speculative Generality
(夸夸其谈未来性)
现象:系统中出现一些无用的
abstract class
,或者非必要的
delegation
(委托),或者多余的参数等等。
重构策略:分别使用
Collapse Hierarchy
合并
abstract class
,使用
Inline Class
移除非必要的
delegation
,使用
Remove Parameter
删除多余的参数。
14
.
Temporary Field
(令人迷惑的暂时值域)
现象:
class
中存在一些
Field
,这些
Field
只在某种非常特定的情况下需要。
重构策略:通过
Extract Class
将这些孤独的
Field
及其相关的
Method
移植的一些新的
Class
中。提炼出来的新
Class
可能没有任何抽象意义,只是提供
Method
的调用,这些新
Class
一般称为
Method Object
。
15
.
Message Chains
(过度耦合的消息链)
现象:向一个对象请求另一个对象,然后再向后者请求另一个对象,……,这就是
Message Chain
,意味着
Message Chain
中任何改变,将导致
Client
端不得不修改。
重构策略:通过
Hide Delegate
(隐藏委托关系)消除
Message Chain
,具体做法是在
Message Chain
的任何地方通过
Extract Method
建立一个简单委托(
Delegation
)函数,来减少耦合(
Coupling
)。
16
.
Middle Man
(中间转手人)
现象:过度运用
delegation
,某个
/
某些
Class
接口有一半的函数都委托给其他
class
,这样就是过度
delegation
。
重构策略:运用
Remove Middle Man
,移除简单的委托动作(也就是移除委托函数),让
client
直接调用
delegate
受托对象。和上面的
Hide Delegate
(隐藏委托关系)刚好相反的过程。
由于系统在不断的变化和调整,因此
[
合适的隐藏程度
]
这个尺度也在相应的变化,
Hide Delegate
和
Remove Middle Man
重构策略可以系统适应这种变化。
另外,可保留一部分委托关系(
delegation
),同时也让
Client
也直接使用
delegate
受托对象。
17
.
Inappropriate Intimacy
(狎昵关系)
现象:两个
Class
过分亲密,彼此总是希望了解对方的
private
成分。
重构策略:可以采用
Move Method
和
Move Field
来帮助他们划清界限,减少他们之间亲密行为。或者运用
Change Bidirectional Association to Unidirectional
,将双向关联改为单向,降低
Class
之间过多的依存性(
inter-dependencies
)。或者通过
Extract Class
将两个
Class
之间的共同点移植到一个新的
Class
中。
18
.
Alternative Classes with Different Interfaces
(异曲同工的类)
现象:两个函数做相同的事情,却有不同的
signature
。
重构策略:使用
Rename Method
,根据他们的用途来重命名。另外,可以适当运用
Move Method
迁移某些行为,使
Classes
的接口保持一致。
19
.
Incomplete Library Class
(不完美的程序库类)
现象:
Library Class
(类库)设计不是很完美,我们需要添加额外的方法。
重构策略:如果可以修改
Library Class
的
Source Code
,直接修改最好。如果无法直接修改
Library Class
,并且只想修改
Library Class
内的一两个函数,可以采用
Introduce Foreign Method
策略:在
Client Class
中建立一个函数,以外加函数的方式来实现一项新功能(一般而言,以
server class
实例作为该函数的第一个参数)。
如果需要建立大量的额外函数,可应该采用
Introduce Local Extension
:建立一个新
class
,使它包含额外函数,并且这个
class
或者继承或者
wrap
(包装)
source class
。
20
.
Data Class
(纯稚的数据类)
现象:
Data Class
指:一些
Class
拥有
Fields
,以及用来访问
Fields
的
getter/setter
函数,但是没有其他的功能函数。(感觉这些
Data Class
如同
Entity Class
或
Parameter Class
,用来传递参数,我认为这种情况下没有必要重构。)
重构策略:找出其他
class
中访问
Data Class
中的
getter/setter
的函数,尝试以
Move Method
将这些函数移植到
Data Class
中,实现将数据和操作行为(方法)包装在一起,也让
Data Class
承担一定的责任(方法)。
21
.
Refused Bequest
(被拒绝的遗赠)
现象:
Subclass
不想或不需要继承
superclass
的部分函数和
Field
。
重构策略:为
subclass
新建一个兄弟(
sibling class
),再运用
Push Down Method
和
Push Down Field
将
superclass
中的相应函数和
Field
下推到兄弟
class
,这样
superclass
就只包含
subclass
共享的东西了。其实,也就是将
superclass
中一些与特定的函数和
Field
放到特定的
subclass
中,
superclass
中仅包含
subclass
共享的函数和
Field
。
如果不想修改
superclass
,还可以运用
Replace Inheritance with Delegation
来达到目的。也就是以委托取代继承,在
subclass
中新建一个
Field
来保存
superclass
对象,去除
subclass
对
superclass
的继承关系,委托或调用
superclass
的方法来完成目的。
22
.
Comments
(过多的注释)
现象:(晕倒,这个也要重构,
Remove
掉所有的
Comments
吗?不是。)当代码中出现一段长长的注释,一般是由于代码比较糟糕,需要进行重构,除去代码的坏味道。
重构策略:通过上面提及的各种重构策略,将代码的坏味道去除,使注释变成多余。
如果需要注释
/
解释一段代码做了什么,则可以试试
Extract Method
,提取出一个独立的函数,让函数名称解释该函数的用途
/
功能。另外,如果觉得需要注释来说明系统的某些假设条件,
也可尝试使用
Introduce Assertion
(引入断言),来明确标明这些假设。
当你感觉需要撰写注释时,请先尝试重构,试着让所有的注释都变得多余。
代码的坏味道(
Bad Smell in Codes
)学习完了,走完了第一步。后面的内容也翻过多次,感觉还是蛮好懂的。嗯,今天掌握了挑别人代码毛病的精锐武器。郁闷的是,自己写的代码也需要重构。