以下是《重构》一书中"重新组织数据"章节涉及的 16 条重构手法。

  1. Self Encapsulate Field(自封装字段):当你直接访问一个字段,但字段之间的耦合变得笨拙时,为该字段建立 setter/getter,并只通过这些函数来访问字段。
  2. Replace Data Value with Object(以对象取代数据值):当你有一个数据项,需要与其他数据和行为一起才有意义时,将该数据项变为对象。
  3. Change Value to Reference(将值对象改为引用对象):当你从一个类衍生出许多彼此相等的实例,并希望把它们替换为同一个对象时,将这个值对象变为引用对象。
  4. Change Reference to Value(将引用对象改为值对象):当你有一个引用对象,体积很小、不可变且不易管理时,将它变为一个值对象。
  5. Replace Array with Object(以对象取代数组):当你有一个数组,其中的元素各自代表不同的东西时,以对象替换数组,对于数组中的每个元素,用一个字段来表示。
  6. Duplicate Observed Data(复制"被监视数据"):当你有一些领域数据置身于 GUI 控件中,而领域函数需要访问这些数据时,将该数据复制到一个领域对象中,并建立 Observer 模式,用于同步领域对象和 GUI 对象内的重复数据。
  7. Change Unidirectional Association to Bidirectional(将单向关联改为双向关联):当两个类都需要使用对方的特性,但其间只有一条单向链接时,添加一个反向指针,并修改函数以同时更新两条链接。
  8. Change Bidirectional Association to Unidirectional(将双向关联改为单向关联):当两个类之间有双向关联,但其中一个类如今不再需要另一个类的特性时,去除不必要的关联。
  9. Replace Magic Number with Symbolic Constant(以字面常量取代魔数):当你有一个字面数值,带有特别含义时,创建一个常量,根据其意义为它命名,并用这个常量替换该字面值。
  10. Encapsulate Field(封装字段):当你的类中存在一个 public 字段时,将它声明为 private,并提供相应的访问函数。
  11. Encapsulate Collection(封装集合):当有一个函数返回一个集合时,让这个函数返回该集合的一个只读副本,并在这个类中提供添加和移除集合元素的函数。
  12. Replace Record with Data Class(以数据类取代记录):例如查询数据库时,使用类来替代记录会更好。
  13. Replace Type Code with Class(以类取代类型码):当类中有一个数值类型码,但它并不影响类的行为时,用一个新的类来替换该数值码。
  14. Replace Type Code with Subclass(以子类取代类型码):当你有一个不可变的类型码,且它会影响类的行为时,用子类取代这个类型码。
  15. Replace Type Code with State/Strategy(以 State/Strategy 取代类型码):当你有一个类型码,它会影响类的行为,但你无法通过继承来消除它时,以状态对象取代类型码。

    做法:在超类中建立一个查询函数用于返回状态码;在每个子类中重写该函数,返回确切的状态码;在原类中建立一个字段来保存新建的状态对象;调整原类中负责查询类型码的函数,把查询动作转发给状态对象;调整原类中为类型码设置的函数,将恰当的状态对象子类实例赋值给保存状态对象的那个字段。

  16. Replace Subclass with Fields(以字段取代子类):当各个子类的唯一差别只在返回常量数据的函数身上时,修改这些函数使它们返回超类中的某个字段,然后销毁子类。