重构-Java(代码的坏味道)

1. Duplicate Code(重复代码)

  • 同一个类的两个函数含有相同的表达式-Extract Method
  • 两个互为兄弟的子类的含有相同的表达式-Extract Method,Pull Up Method,Template Pattern
  • 两个不相关的类出现Duplicate Code,对其中一个使用Extract Class

2. Long Method(过长函数)

  • 把函数变小-Extract Method
  • 大量的参数和临时变量-Replace Temp With Query,Introduce Parameter Object,Preserve Whole Object,Replace Method With Method Object消除临时变量元素,Decompose Conditional处理条件表达式

3. Large Class(过大的类)

  • 如果类的数个变量有着相同的前缀或结尾,或者是太多的实例变量,太多代码-Extract SubClass,Extract Class
  • Extract Interface,为每一种使用方式提炼出一个接口

4. Long Parameter List(过长参数列)

  • 向已有对象发出一个请求取代一个参数-Replace Parameter With Method
  • 来自同一对象的数据收集起来-Preserve Whole Object
  • 制造一个“参数对象”-Introduce Parameter Object

5. Divergent Change(发散式变化)-一个类受多种变化的影响

  • 某特定原因而造成的变化-Extract Class提炼到同一个类中

6. Shotgun Surgery(霰弹式修改)-一种变化引发多个类的相应修改

  • 需要修改的代码的问题散步四处-Move Method和Move Field把需要修改的代码放进同一个类中,如眼下没有合适的类就创造一个,Inline class把一系列相关行为放进一个类

7. Feature Envy(依恋情结)

  • Strategy和Visitor,可以轻松地修改函数行为(代价:多了一层间接层)

8. Data Clumps

  • 将各个类中相同的字段、函数签名中相同的参数-运行Extract Method提炼到一个类中
  • 运用Introduce Method和Preserve Whole Object为其减肥

9. Primitive Obsession(基本类型偏执)

  • 小任务上运行小对象-Replace Data Value With Object
  • 如果想要替换的数据值是类型码-运用Replace Type Code With Class将其换掉
  • 如果有与类型码相关的条件表达式-Replace Type Code With Subclass 或 Replace Type Code With State/Strategy
  • 如果在参数列表中看到的基本数据型数据-Introduce Parameter Object
  • 从数组中挑选数据-Replace Array With Object

10. Switch Statements

  • Replace Conditional With Polymorphism - 以多态取代条件式

你手上有个条件式,它根据对象型别的不同而选择不同的行为。将这个条件式的每个分支放进一个subclass内的覆写函数中,然后将原始函数声明为抽象函数。

  • Replace Parameter with Explicit Methods - 以明确函数取代参数

你有一个函数,其内完全取决于参数值而采取不同反应。针对该参数的每一个可能值,建立一个独立函数。

11. Parallel Inheritance Hierarchies(平行继承体系)

如果你发现一个继承体系的类名称前缀和另一个体系的类名称前缀完全相同,那便是这种怀味道。
解决的一般策略为:让一个继承体系的实例去引用另一个继承体系的实例。

  • Move Method
  • Move Field

12. Lazy Class(冗赘类)

  • 如果某些子类没有做足够的工作 - Collapse Hierarchy(折叠继承体系),superclass和subclass之间无太大区别。将它们和为一体。
  • 对几乎没有用的组件 - Inline class(你的某个class没有做太多的事情(没有承担足够的责任)。将class的所有特性搬移到另一个class中,然后移除原class。)

13. Speculative Generality

当有人说“喔,我想我们总有一天要做这事”,并因而企图用各式各样的钩子和特殊情况来处理一些非必要的事情。

  • Remove Parameter
  • Rename Method

14. Temporary Field(临时字段)

15. Message Chain(过度耦合的消息链)

一个对象请求另一个对象,然后再向后者请求另一个对象…这就是消息链,这样可能会导致对象间的关系发生变化时,客户端不得不做出相应的修改。

  • Hide Delegate(隐藏委托关系)

客户直接调用其server object(服务对象)的delegate class。在sever端(某个class)建立客户所需要的所有函数,用以隐藏委托关系。

16. Middle Man

  • InlineMethod - 移除函数,将其放入调用端。

  • Replace Delegation with Inheritanc (以继承取代委托)
    你的两个classes之间使用了委托关系,并经常为整个接口编写许多极其简单的请托函数。让请托Class继承受托class。

17. Inappropriate Intimacy

  • .Change Bindirectional Association to Unidirectional 将双向关联改为单向(两个classes之间有双向关联,但其中一个class如今不再需要另一个class的特性。去除不必要的关联(association)。)

  • Replace Inheritance with Delegation(以委托取代继承) - 某个subclass只使用superclass接口中的一部分,或是更本不需要继承而来的数据。在subclass中新建一个值域用以保存superclass;调整subclass函数,令它改而委托superclass;然后去掉两者之间的继承关系。

18. Alternative Classes With Different Interfaces

  • Extract Superclass

19. Incomplete Library Class(不完全的库类)

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

你所使用的server class 需要一个额外函数,但你无法修改这个class。在client class 中建立一个函数,并以一个server class实体作为第一引数(argument)。

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

20. Data Class (数据类)

  • Self Encapsulate Field(自封装值域)- 你直接访问一个值域(field),但与值域直接的耦合关系变得逐渐变得笨拙。为这个值域建立取值/设值函数,并且只有这些函数来访问值域。
  • Encapsulate collection (封装群集)
  • Remove Setting Method(移除设值函数)- 你的class中的某个值域,应该在对象初创时被设值,然后就不再改变。去掉该值域的所有设置函数。

21. Refused Bequest(拒绝遗赠)

22. Comments(过多的注释)

  • Introduce Assertion(引入断言)- 某一段代码需要对程序状态做出某种假设。以assertion(断言)明确表现这种假设。
  • Extract Method
  • Rename Method
  • 当你感觉需要写注释时,请先尝试重构,试着让所有的注释都变得多余。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章