`
luoshi0801
  • 浏览: 145962 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论
阅读更多

重构—对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。

 

代码坏味道

常用重构手段

Duplicated重复代码

Extract Method

Extract Class

Pull Up Method

Form Template Method

Long Method 过长函数

Extract Method

Replace Temp With Query

Replace Method With Method Object

Decompose Conditional

Large Class 过大的类

Extract Class

Extract Subclass

Extract Interface

Replace Data Value With Object

Long Parameter List 过长参数列

Replace Parameter With Method

Introduce Parameter Object

Preserve Whole Object

Divergent Change 发散式变化

Extract Class

Shotgun Surgery散弹式修改

Move Method

Move Field

Inline Class

Feature Envy 依恋情结

Move Method

Move Field

Extract Method

Data Clumps 数据泥团

Extract Class

Introduce Parameter Object

Preserve Whole Object

Primitive Obsession 基本类型偏执

Replace Data Value With Object

Extract Class

Introduce Parameter Object

Replace Array with Object

Replace Type Code With Class

Replace Type Code With Subclasses

Replace Type Code With State/Strategy

Switch Statements switch惊悚现身

Replace Conditional With Polymorphisrn

Replace Type Code With Subclasses

Replace Type Code With State/Strategy

Replace Parameter With Explicit Methods

Introduce Null Object

Parallel Inheritance Hierarchies 平行继承体系

Move Method

Move Field

Lazy Class 冗赘类

Inline Class

Collapse Hierarchy

Speculative Generality 夸夸其谈未来性

Collapse Hierarchy

Inline Class

Remove Parameter

Rename Method

Temporary Field 令人迷惑的暂时字段

Extract Class

Introduce Null Object

Message Chains 过度耦合的消息链

Hide Delegate

Middle Man 中间人

Remove Middle Man

Inline Method

Replace Delegation With Inheritance

Inappropriate Intimacy 狎昵关系

Move Method

Move Field

Change Bidirectional Association to Unidirectional

Replace Inheritance With Delegation

Hide Delegate

Alternative Classes with Different Interfaces 异曲同工的类

Rename Method

Move Method

Incomplete Library Class 不完美的库类

Introduce Foreign Method

Introduce Local Extension

Data Class 纯稚的数据类

Move Method

Encapsulate Field

Encapsulate Colletion

Refused Bequest 被拒绝的遗赠

Replace Inheritance With Delegation

Comments 过多的注释

Extract Method

Introduce Assertion

 

重构列表:

l  重新组织函数

Ø  Extract Method(提取函数)

有一段代码可以被组织在一起并独立出来

将这段代码放进一个独立函数中,并让函数名称解释该函数的用途

Ø  Inline Method(将函数)

一个函数,其本地应该与其名称同样清楚易懂

在函数调用点插入函数本地,然后移除该函数

Ø  Inline Temp(将临时变量内联化)

有一个变量,只被一个简单表达式赋值一次,而它妨碍了其他重构手法

将所有对该变量的引用动作,替换为对它赋值的那个表达式本身

Ø  Replace Temp With Query(以查询取代临时变量)

程序以一个临时变量保存某一表达式的运算结果

将这个表达式提炼到一个独立函数中,将这个临时变量的所有被引用点替换为对新函数的调用。新函数可被其他函数使用

Ø  Introduce Explaining Variable(引入解释性变量)

有一个复杂的表达式

将该表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式用途

Ø  Split Temporary Variable(剖解临时变量)

程序有某个临时变量被赋值超过一次,它既不是循环变量,也不是一个集用临时变量

针对每次赋值,创造一个独立的、对应的临时变量

Ø  Remove Assignments to Parameters(移除对参数的赋值动作)

代码对一个参数进行赋值动作

以一个临时变量取代该参数的位置

Ø  Replace Method With Method Object(以函数对象取代函数)

有一个大型函数,其中对局部变量的使用,使得无法采用Extract Method

将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的值域,然后可以再同一个对象中将这个大型函数分解为数个小型函数

Ø  Substitute Algorithm(替换算法)

把某个算法替换为另一个更清晰的算法

将函数本体替换为另一个算法

l  在对象之间搬移特性

Ø  Move Method(搬移函数)

在程序中,有个函数与其所驻class之外的另一个class进行更多交流:调用后者,或被后者调用

Ø  Move Field(搬移值域)

在程序中,某个field被其所驻class之外的另一个class更多地用到

target class建立一个new field,修改source field的所有用户,令它们改用此new field

Ø  Extract Class(提炼类)

某个class做了应该由两个classes做的事

建立一个新class,将相关的值域和函数从旧class搬移到新class

Ø  Inline Class(将类内联化)

某个class没有做太多的事情(没有承担足够责任)

class的所有特性搬移到另一个class中,然后移除原class

Ø  Hide Delegate(隐藏委托关系)

客户直接调用其server objectdelegate class

server端建立客户所需的所有函数,用以隐藏委托关系

Ø  Remove Middle Man(移除中间人)

某个class做了过多的简单委托动作

让客户直接调用delegate

Ø  Introduce Foreign Method(引入外加函数)

所使用的server class需要一个额外函数,但无法修改这个class

client class中建立一个函数,并以一个server class实体作为第一参数

Ø  Introduce Local Extension(引入本地扩展)

使用的server class需要一些额外函数,但无法修改这个class

建立一个新class,使它包含这些额外函数。让这个扩展品成为source classsubclasswrapper

l  重新组织数据

Ø  Self Encapsulate Field(自封装值域)

直接访问一个field,但与值域之间的耦合关系逐渐变得笨拙

为这个值域建立取值/设置函数,并且只以这些函数来访问值域

Ø  Replace Data Value With Object(以对象取代数据值)

有一笔数据项(data item),需要额外的数据和行为

将这笔数据项变成一个对象

Ø  Change Value to Reference(将实值对象改为引用对象)

有一个class,衍生出许多相等尸体,希望将它们替换为单一对象

将这个value object变成一个reference object

Ø  Change Reference to Value(将引用对象改为实值对象)

有一个reference object,很小且不可变,而且不易管理

将它变成一个value object

Ø  Replace Array With Object(以对象取代数组)

有一个数组,其中的元素各自代表不同的东西

以对象替换数组。对于数组中的每个元素,以一个值域表示之

Ø  Duplicate Observed Data(复制被监视数据)

有一些domain class置身于GUI控件中,而domain method需要访问之

将改笔数据拷贝到一个domain object中。建立一个Observer模式,用以对domain objectGUI object内的重复数据进行同步控制

Ø  Change Unidirectional Association to Bidirectional(将单向关联改为双向)

两个classes都需要使用对方特性,但其间只有一条单向连接

添加一个反向指针,并使修改函数能够同时更新两条连接

Ø  Change Bidirectional Association to Unidirectional(将双向关联改为单向)

两个classes之间有双向关联,但其中一个class如今不再需要另一个class的特性

去除不必要的关联

Ø  Replace Magic Number With Symbolic Constant(以符号常量/字面常量取代魔法数)

有一个字面数值,带有特别含义

创造一个常量,根据其意义为它命名,并将上述的字面数值替换为这个常量

Ø  Encapsulate Field(封装值域)

Class中存在一个public值域

将它声明为private,并提供相应的访问函数

Ø  Replace Record With Data Class(以数据类取代记录)

需要面对传统编程环境中的record structure

为该record创建一个哑数据对象(dumb data object

Ø  Replace Type Code With Class(以类取代型别码)

Class之中有一个数值型别码,但它并不影响class的行为

以一个新的class替换该数值型别码

Ø  Replace Type Code With Subclasses(以子类取代型别码)

有一个不可变的type code,它会影响class的行为

以一个subclass取代这个type code

Ø  Replace Type Code With State/Strategy(以State/Strategy取代型别码)

有一个type code,它会影响class的行为,但无法使用subclassing

state object取代type code

Ø  Replace Subclass With Fields(以值域取代子类)

各个subclasses的惟一差别只在返回常量数据的函数身上

修改这些函数,使它们返回superclass中的某个(新增)值域,然后销毁subclasses

l  简化条件表达式

Ø  Decompose Conditional(分解条件式)

有一个复杂的条件(if-then-else)语句

ifthenelse三个段落中分别提炼出独立函数

Ø  Consolidate Conditional Expression(合并条件式)

有一系列条件测试,都得到相同结果

将这些测试合并为一个条件式,并将这个条件式提炼成为一个独立函数

Ø  Consolidate Duplicate Conditional Fragments(合并重复的条件片段)

在条件式的每个分支上有着相同的一段代码

将这段重复代码搬移到条件式之外

Ø  Remove Control Flag(移除控制标记)

在一系列布尔表达式中,某个变量带有控制标记(control flag)的作用

break语句或return语句取代控制标记

Ø  Replace Nested Conditional With Guard Clauses(以卫语句取代嵌套条件式)

函数中的条件使人难以看清正常的执行路径

使用卫语句(guard clauses)表现所有特殊情况

Ø  Replace Conditional With Polymorphism(以多态取代条件式)

有个条件式,它根据对象类别的不同而选择不同的行为

将这个条件式的每个分支放进一个subclass内的覆写函数中,然后将原始函数声明为抽象函数

Ø  Introduce Null Object(引入Null对象)

需要再三检查某物是否为null value

null value替换为null object

Ø  Introduce Assertion(引入断言)

某一段代码需要对程序状态做出某种假设

assertion明确表现这种假设

l  简化函数调用

Ø  Rename Method(重新命名函数)

函数的名称未能揭示函数的用途

修改函数名称

Ø  Add Parameter(添加参数)

某个函数需要从调用端得到更多信息

为此函数添加一个对象函数,让该对象带函数所需信息

Ø  Remove Parameter(移除参数)

函数本体不再需要某个函数

将该函数去除

Ø  Separate Query from Modifier(将查询函数和修改函数分离)

某个函数既返回对象状态值,又修改对象状态

建立两个不同的函数,其中一个负责查询,另一个负责修改

Ø  Parameterize Method(令函数携带参数)

若干函数做了类似的工作,但在函数本体中却包含了不同的值

建立单一函数,以参数表达那些不同的值

Ø  Replace Parameter With Explicit Methods(以明确函数取代参数)

有一个函数,其内完全取决于参数值而采取不同反应

针对该参数的每一个可能值,建立一个独立函数

Ø  Preserve Whole Object(保持对象完整)

从某个对象中取出若干值,将它们作为某一次函数调用时的参数

改使用(传递)整个对象

Ø  Replace Parameter With Method(以函数取代参数)

对象调用某个函数,并将所得结果作为参数,传递给另一个函数。而接受该参数的函数也可以(也有能力)调用前一个函数

让参数接受者去除该项参数,并直接调用前一个函数

Ø  Introduce Parameter Object(引入参数对象)

某些参数总是很自然地同时出现

以一个对象取代这些参数

Ø  Remove Setting Method(移除设置函数)

Class中的某个域值,应该在对象初创时被设置,然后就不再改变

去掉该值域的所有设值函数

Ø  Hide Method(隐藏某个函数)

有一个函数,从来没有被其他任何class用到

将这个函数修改为private

Ø  Replace Constructor With Factory Method(以工厂函数取代构造函数)

希望在创建对象时不仅仅是对它做简单的建构动作

constructor替换为factory method

Ø  Encapsulate Downcast(封装向下转型动作)

某个函数返回的对象,需要由函数调用者执行向下转型动作

将向下转型动作移到函数中

Ø  Replace Error Code With Exception(用异常取代错误码)

某个函数返回一个特定的代码,用以表示某种错误情况

改用异常

Ø  Replace Exception With Test(以测试取代异常)

面对一个调用者可预先加以检查的条件,抛出一个异常

修改调用者,使它在调用函数之前先做检查

l  处理概括关系

Ø  Pull Up Field(值域上移)

两个subclasses拥有相同的值域

将此值域移至superclass

Ø  Pull Up Method(函数上移)

有些函数,在各个subclass中产生完全相同的结果

将该函数移至superclass

Ø  Pull Up Constructor Body(构造函数本体上移)

在各个subclass中拥有一些构造函数,它们的本体代码几乎完全一致

superclass中新建一个构造函数,并在subclass构造函数中调用它

Ø  Push Down Method(函数下移)

Superclass中的某个函数只与部分(而非全部)subclasses有关

将这个函数移到相关的那些subclasses

Ø  Push Down Field(值域下移)

Superclass中的某个值域只被部分(而非全部)subclasses用到

将这个值域移到需要它的那些subclasses

Ø  Extract Subclass(提炼子类)

Class中的某些特性只被某些(而非全部)实体用到

新建一个subclass,将上面所说的那一部分特性移到subclass

Ø  Extract Superclass(提炼超类)

两个classes有相似特性

为这两个classes建立一个superclass,将相同特性移至superclass

Ø  Extract Interface(提炼接口)

若干客户使用class接口中的同一子集;或者,两个classes的接口有部分相同

将相同的子集提炼到一个独立接口中

Ø  Collapse Hierarchy(折叠继承关系)

Superclasssubclass之间无太大区别

将它们合为一体

Ø  Form Template Method(塑造模板函数)

有一些subclasses,其中相应的某些函数以相同顺序执行类似的措施,但各措施实际上有所不同

将各个措施分别放进独立函数中,并保持它们都有相同的签名式(signature),于是原函数也就变得相同了。然后将原函数上移至superclass

Ø  Replace Inheritance with Delegation(以委托取代继承)

某个subclass只使用superclass接口中的一部分,或是根本不需要继承而来的数据

subclass中新建一个值域用以保存superclass;调整subclass函数,令它改而委托superclass;然后去掉两者之间的继承关系

Ø  Replace Delegation With Inheritance(以继承取代委托)

在两个classes之间使用委托关系,并经常为整个接口编写许多极简单的请托函数

让请托(delegatingclass继承受托class

l  大型重构

Ø  Tease Apart Inheritance(梳理并分解继承体系)

某个继承体系同时承担两项责任

建立两个继承体系,并通过委托关系让其中一个可以调用另一个

Ø  Convert Procedural Design to Objects(将过程化设计转化为对象设计)

有一些代码,以流程的过程化风格写就

将数据记录变成对象,将行为分开,并将行为移入相关对象之中

Ø  Separate Domain from Presentation(将领域和表述/显示分离)

某些GUI class之中包含了domain logic(领域逻辑)

domain logic分离出来,为它们建立独立的domain class

Ø  Extract Hierarchy(提炼继承体系)

某个class做了太多工作,其中一部分工作以大量条件式完成

建立继承体系,以一个subclass表示一种特殊情况

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics