From 7a686e21ab4b6f77cd7899cdb034fa33272e28af Mon Sep 17 00:00:00 2001 From: CyC2018 <1029579233@qq.com> Date: Tue, 20 Mar 2018 10:15:37 +0800 Subject: [PATCH] auto commit --- notes/重构.md | 354 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 236 insertions(+), 118 deletions(-) diff --git a/notes/重构.md b/notes/重构.md index 92a35946..db9cb993 100644 --- a/notes/重构.md +++ b/notes/重构.md @@ -44,69 +44,69 @@ * [8. 以函数对象取代函数](#8-以函数对象取代函数) * [9. 替换算法](#9-替换算法) * [六、在对象之间搬移特性](#六在对象之间搬移特性) - * [1. Move Method(搬移函数)](#1-move-method搬移函数) - * [2. Move Field(搬移字段)](#2-move-field搬移字段) - * [3. Extract Class(提炼类)](#3-extract-class提炼类) - * [4. Inline Class(将类内联化)](#4-inline-class将类内联化) - * [5. Hide Delegate(隐藏“委托关系”)](#5-hide-delegate隐藏“委托关系”) - * [6. Remove Middle Man(移除中间人)](#6-remove-middle-man移除中间人) - * [7. Introduce Foreign Method(引入外加函数)](#7-introduce-foreign-method引入外加函数) - * [8. Introduce Local Extension(引入本地扩展)](#8-introduce-local-extension引入本地扩展) + * [1. 搬移函数](#1-搬移函数) + * [2. 搬移字段](#2-搬移字段) + * [3. 提炼类](#3-提炼类) + * [4. 将类内联化](#4-将类内联化) + * [5. 隐藏委托关系](#5-隐藏委托关系) + * [6. 移除中间人](#6-移除中间人) + * [7. 引入外加函数](#7-引入外加函数) + * [8. 引入本地扩展](#8-引入本地扩展) * [七、重新组织数据](#七重新组织数据) - * [1. Self Encapsulate Field(自封装字段)](#1-self-encapsulate-field自封装字段) - * [2. Replace Data Value with Object(以对象取代数据值)](#2-replace-data-value-with-object以对象取代数据值) - * [3. Change Value to Reference(将值对象改成引用对象)](#3-change-value-to-reference将值对象改成引用对象) - * [4. Change Reference to value(将引用对象改为值对象)](#4-change-reference-to-value将引用对象改为值对象) - * [5. Replace Array with Object(以对象取代数组)](#5-replace-array-with-object以对象取代数组) - * [6. Duplicate Observed Data(赋值“被监视数据”)](#6-duplicate-observed-data赋值“被监视数据”) - * [7. Change Unidirectional Association to Bidirectional(将单向关联改为双向关联)](#7-change-unidirectional-association-to-bidirectional将单向关联改为双向关联) - * [8. Change Bidirectional Association to Unidirectional(将双向关联改为单向关联)](#8-change-bidirectional-association-to-unidirectional将双向关联改为单向关联) - * [9. Replace Magic Number with Symbolic Constant(以字面常量取代魔法数)](#9-replace-magic-number-with-symbolic-constant以字面常量取代魔法数) - * [10. Encapsulate Field(封装字段)](#10-encapsulate-field封装字段) - * [11. Encapsulate Collection(封装集合)](#11-encapsulate-collection封装集合) - * [12. Replace Record with Data Class(以数据类取代记录)](#12-replace-record-with-data-class以数据类取代记录) - * [13. Replace Type Code with Class(以类取代类型码)](#13-replace-type-code-with-class以类取代类型码) - * [14. Replace Type Code with Subcalsses(以子类取代类型码)](#14-replace-type-code-with-subcalsses以子类取代类型码) - * [15. Replace Type Code with State/Strategy (以 State/Strategy 取代类型码)](#15-replace-type-code-with-statestrategy-以-statestrategy-取代类型码) - * [16. Replace Subclass with Fields(以字段取代子类)](#16-replace-subclass-with-fields以字段取代子类) + * [1. 自封装字段](#1-自封装字段) + * [2. 以对象取代数据值](#2-以对象取代数据值) + * [3. 将值对象改成引用对象](#3-将值对象改成引用对象) + * [4. 将引用对象改为值对象](#4-将引用对象改为值对象) + * [5. 以对象取代数组](#5-以对象取代数组) + * [6. 赋值被监视数据](#6-赋值被监视数据) + * [7. 将单向关联改为双向关联](#7-将单向关联改为双向关联) + * [8. 将双向关联改为单向关联](#8-将双向关联改为单向关联) + * [9. 以字面常量取代魔法数](#9-以字面常量取代魔法数) + * [10. 封装字段](#10-封装字段) + * [11. 封装集合](#11-封装集合) + * [12. 以数据类取代记录](#12-以数据类取代记录) + * [13. 以类取代类型码](#13-以类取代类型码) + * [14. 以子类取代类型码](#14-以子类取代类型码) + * [15. 以 State/Strategy 取代类型码](#15-以-statestrategy-取代类型码) + * [16. 以字段取代子类](#16-以字段取代子类) * [八、简化条件表达式](#八简化条件表达式) - * [1. Decompose Conditional(分解条件表达式)](#1-decompose-conditional分解条件表达式) - * [2. Consolidate Conditional Expression(合并条件表达式)](#2-consolidate-conditional-expression合并条件表达式) - * [3. Consolidate Duplicate Conditional Fragments (合并重复的条件片段)](#3-consolidate-duplicate-conditional-fragments-合并重复的条件片段) - * [4. Remove Control Flag(移除控制标记)](#4-remove-control-flag移除控制标记) - * [5. Replace Nested Conditional with Guard Clauses (以卫语句取代嵌套条件表达式)](#5-replace-nested-conditional-with-guard-clauses-以卫语句取代嵌套条件表达式) - * [6. Replace Conditional with Polymorphism (以多态取代条件表达式)](#6-replace-conditional-with-polymorphism-以多态取代条件表达式) - * [7. Introduce Null Object(引入Null对象)](#7-introduce-null-object引入null对象) - * [8. Introduce Assertion(引入断言)](#8-introduce-assertion引入断言) + * [1. 分解条件表达式](#1-分解条件表达式) + * [2. 合并条件表达式](#2-合并条件表达式) + * [3. 合并重复的条件片段](#3-合并重复的条件片段) + * [4. 移除控制标记](#4-移除控制标记) + * [5. 以卫语句取代嵌套条件表达式](#5-以卫语句取代嵌套条件表达式) + * [6. 以多态取代条件表达式](#6-以多态取代条件表达式) + * [7. 引入Null对象](#7-引入null对象) + * [8. 引入断言](#8-引入断言) * [九、简化函数调用](#九简化函数调用) - * [1. Rename Method(函数改名)](#1-rename-method函数改名) - * [2. Add Parameter(添加参数)](#2-add-parameter添加参数) - * [3. Remove Parameter(移除参数)](#3-remove-parameter移除参数) - * [4. Separate Query from Modifier(将查询函数和修改函数分离)](#4-separate-query-from-modifier将查询函数和修改函数分离) - * [5. Parameterize Method(令函数携带参数)](#5-parameterize-method令函数携带参数) - * [6. Replace Parameter with Explicit Methods(以明确函数取代参数)](#6-replace-parameter-with-explicit-methods以明确函数取代参数) - * [7. Preserve Whole Object(保持对象完整)](#7-preserve-whole-object保持对象完整) - * [8. Replace Parameter with Methods(以函数取代参数)](#8-replace-parameter-with-methods以函数取代参数) - * [9. Introduce Parameter Object(引入参数对象)](#9-introduce-parameter-object引入参数对象) - * [10. Remove Setting Method(移除设值函数)](#10-remove-setting-method移除设值函数) - * [11. Hide Method(隐藏函数)](#11-hide-method隐藏函数) - * [12. Replace Constructor with Factory Method (以工厂函数取代构造函数)](#12-replace-constructor-with-factory-method-以工厂函数取代构造函数) - * [13. Encapsulate Downcast(封装向下转型)](#13-encapsulate-downcast封装向下转型) - * [14. Replace Error Code with Exception (以异常取代错误码)](#14-replace-error-code-with-exception-以异常取代错误码) - * [15. Replace Exception with Test(以测试取代异常)](#15-replace-exception-with-test以测试取代异常) + * [1. 函数改名](#1-函数改名) + * [2. 添加参数](#2-添加参数) + * [3. 移除参数](#3-移除参数) + * [4. 将查询函数和修改函数分离](#4-将查询函数和修改函数分离) + * [5. 令函数携带参数](#5-令函数携带参数) + * [6. 以明确函数取代参数](#6-以明确函数取代参数) + * [7. 保持对象完整](#7-保持对象完整) + * [8. 以函数取代参数](#8-以函数取代参数) + * [9. 引入参数对象](#9-引入参数对象) + * [10. 移除设值函数](#10-移除设值函数) + * [11. 隐藏函数](#11-隐藏函数) + * [12. 以工厂函数取代构造函数](#12-以工厂函数取代构造函数) + * [13. 封装向下转型](#13-封装向下转型) + * [14. 以异常取代错误码](#14-以异常取代错误码) + * [15. 以测试取代异常](#15-以测试取代异常) * [十、处理概括关系](#十处理概括关系) - * [1. Pull Up Field(字段上移)](#1-pull-up-field字段上移) - * [2. Pull Up Method(函数上移)](#2-pull-up-method函数上移) - * [3. Pull Up Constructor Body(构造函数本体上移)](#3-pull-up-constructor-body构造函数本体上移) - * [4. Push Down Method(函数下移)](#4-push-down-method函数下移) - * [5. Push Down Field(字段下移)](#5-push-down-field字段下移) - * [6. Extract Subclass(提炼子类)](#6-extract-subclass提炼子类) - * [7. Extract Superclass(提炼超类)](#7-extract-superclass提炼超类) - * [8. Extract Interface(提炼接口)](#8-extract-interface提炼接口) - * [9. Collapse Hierarchy(折叠继承体系)](#9-collapse-hierarchy折叠继承体系) - * [10. Form Template Method(塑造模板函数)](#10-form-template-method塑造模板函数) - * [11. Replace Inheritance with Delegation (以委托取代继承)](#11-replace-inheritance-with-delegation-以委托取代继承) - * [12. Replace Delegation with Inheritance (以继承取代委托)](#12-replace-delegation-with-inheritance-以继承取代委托) + * [1. 字段上移](#1-字段上移) + * [2. 函数上移](#2-函数上移) + * [3. 构造函数本体上移](#3-构造函数本体上移) + * [4. 函数下移](#4-函数下移) + * [5. 字段下移](#5-字段下移) + * [6. 提炼子类](#6-提炼子类) + * [7. 提炼超类](#7-提炼超类) + * [8. 提炼接口](#8-提炼接口) + * [9. 折叠继承体系](#9-折叠继承体系) + * [10. 塑造模板函数](#10-塑造模板函数) + * [11. 以委托取代继承](#11-以委托取代继承) + * [12. 以继承取代委托](#12-以继承取代委托) @@ -537,27 +537,37 @@ int discount (int inputVal, int quentity, int yearToDate){ # 六、在对象之间搬移特性 -## 1. Move Method(搬移函数) +## 1. 搬移函数 + +> Move Method 类中的某个函数与另一个类进行更多交流:调用后者或者被后者调用。 将这个函数搬移到另一个类中。 -## 2. Move Field(搬移字段) +## 2. 搬移字段 + +> Move Field 类中的某个字段被另一个类更多地用到,这里的用到是指调用取值设值函数,应当把该字段移到另一个类中。 -## 3. Extract Class(提炼类) +## 3. 提炼类 + +> Extract Class 某个类做了应当由两个类做的事。 应当建立一个新类,将相关的字段和函数从旧类搬移到新类。 -## 4. Inline Class(将类内联化) +## 4. 将类内联化 + +> Inline Class 与 Extract Class 相反。 -## 5. Hide Delegate(隐藏“委托关系”) +## 5. 隐藏委托关系 + +> Hide Delegate 建立所需的函数,隐藏委托关系。 @@ -593,49 +603,67 @@ public Person getManager(){ } ``` -## 6. Remove Middle Man(移除中间人) +## 6. 移除中间人 + +> Remove Middle Man 与 Hide Delegate 相反,本方法需要移除委托函数,让客户直接调用委托类。 Hide Delegate 有很大好处,但是它的代价是:每当客户要使用受托类的新特性时,就必须在服务器端添加一个简单的委托函数。随着受委托的特性越来越多,服务器类完全变成了一个“中间人”。 -## 7. Introduce Foreign Method(引入外加函数) +## 7. 引入外加函数 + +> Introduce Foreign Method 需要为提供服务的类添加一个函数,但是无法修改这个类。 可以在客户类中建立一个函数,并以第一参数形式传入一个服务类的实例,让客户类组合服务器实例。 -## 8. Introduce Local Extension(引入本地扩展) +## 8. 引入本地扩展 + +> Introduce Local Extension 和 Introduce Foreign Method 目的一样,但是 Introduce Local Extension 通过建立新的类来实现。有两种方式:子类或者包装类,子类就是通过继承实现,包装类就是通过组合实现。 # 七、重新组织数据 -## 1. Self Encapsulate Field(自封装字段) +## 1. 自封装字段 + +> Self Encapsulate Field 为字段建立取值/设值函数,并用这些函数来访问字段。只有当子类想访问超类的一个字段,又想在子类中将对这个字段访问改为一个计算后的值,才使用这种方式,否则直接访问字段的方式简洁明了。 -## 2. Replace Data Value with Object(以对象取代数据值) +## 2. 以对象取代数据值 + +> Replace Data Value with Object 在开发初期,往往会用简单的数据项表示简单的情况,但是随着开发的进行,一些简单数据项会具有一些特殊行为。比如一开始会把电话号码存成字符串,但是随后发现电话号码需要“格式化”、“抽取区号”之类的特殊行为。 -## 3. Change Value to Reference(将值对象改成引用对象) +## 3. 将值对象改成引用对象 + +> Change Value to Reference 将彼此相等的实例替换为同一个对象。这就要用一个工厂来创建这种唯一对象,工厂类中需要保留一份已经创建对象的列表,当要创建一个对象时,先查找这份列表中是否已经存在该对象,如果存在,则返回列表中的这个对象;否则,新建一个对象,添加到列表中,并返回该对象。 -## 4. Change Reference to value(将引用对象改为值对象) +## 4. 将引用对象改为值对象 + +> Change Reference to value 以 Change Value to Reference 相反。值对象有个非常重要的特性:它是不可变的,不可变表示如果要改变这个对象,必须用一个新的对象来替换旧对象,而不是修改旧对象。 需要为值对象实现 equals() 和 hashCode() 方法 -## 5. Replace Array with Object(以对象取代数组) +## 5. 以对象取代数组 + +> Replace Array with Object 有一个数组,其中的元素各自代表不同的东西。 以对象替换数组,对于数组中的每个元素,以一个字段来表示,这样方便操作,也更容易理解。 -## 6. Duplicate Observed Data(赋值“被监视数据”) +## 6. 赋值被监视数据 + +> Duplicate Observed Data 一些领域数据置身于 GUI 控件中,而领域函数需要访问这些数据。 @@ -643,7 +671,9 @@ Hide Delegate 有很大好处,但是它的代价是:每当客户要使用受

-## 7. Change Unidirectional Association to Bidirectional(将单向关联改为双向关联) +## 7. 将单向关联改为双向关联 + +> Change Unidirectional Association to Bidirectional 当两个类都需要对方的特性时,可以使用双向关联。 @@ -674,39 +704,55 @@ class Curstomer{ 注意到,这里让 Curstomer 类来控制关联关系。有以下原则来决定哪个类来控制关联关系:如果某个对象是组成另一个对象的部件,那么由后者负责控制关联关系;如果是一对多关系,则由单一引用那一方来控制关联关系。 -## 8. Change Bidirectional Association to Unidirectional(将双向关联改为单向关联) +## 8. 将双向关联改为单向关联 + +> Change Bidirectional Association to Unidirectional 和 Change Unidirectional Association to Bidirectiona 为反操作。 双向关联维护成本高,并且也不易于理解。大量的双向连接很容易造成“僵尸对象”:某个对象本身已经死亡了,却保留在系统中,因为它的引用还没有全部完全清除。 -## 9. Replace Magic Number with Symbolic Constant(以字面常量取代魔法数) +## 9. 以字面常量取代魔法数 + +> Replace Magic Number with Symbolic Constant 创建一个常量,根据其意义为它命名,并将字面常量换位这个常量。 -## 10. Encapsulate Field(封装字段) +## 10. 封装字段 + +> Encapsulate Field public 字段应当改为 private,并提供相应的访问函数。 -## 11. Encapsulate Collection(封装集合) +## 11. 封装集合 + +> Encapsulate Collection 函数返回集合的一个只读副本,并在这个类中提供添加/移除集合元素的函数。如果函数返回集合自身,会让用户得以修改集合内容而集合拥有者却一无所知。 -## 12. Replace Record with Data Class(以数据类取代记录) +## 12. 以数据类取代记录 -## 13. Replace Type Code with Class(以类取代类型码) +> Replace Record with Data Class + +## 13. 以类取代类型码 + +> Replace Type Code with Class 类中有一个数值类型码,但它并不影响类的行为,就用一个新类替换该数值类型码。如果类型码出现在 switch 语句中,需要使用 Replace Conditional with Polymorphism 去掉 switch,首先必须运用 Replace Type Code with Subcalss 或 Replace Type Code with State/Strategy 去掉类型码。

-## 14. Replace Type Code with Subcalsses(以子类取代类型码) +## 14. 以子类取代类型码 + +> Replace Type Code with Subcalsses 有一个不可变的类型码,它会影响类的行为,以子类取代这个类型码。

-## 15. Replace Type Code with State/Strategy (以 State/Strategy 取代类型码) +## 15. 以 State/Strategy 取代类型码 + +> Replace Type Code with State/Strategy 有一个可变的类型码,它会影响类的行为,以状态对象取代类型码。 @@ -714,7 +760,9 @@ public 字段应当改为 private,并提供相应的访问函数。

-## 16. Replace Subclass with Fields(以字段取代子类) +## 16. 以字段取代子类 + +> Replace Subclass with Fields 各个子类的唯一差别只在“返回常量数据”的函数上。 @@ -722,7 +770,9 @@ public 字段应当改为 private,并提供相应的访问函数。 # 八、简化条件表达式 -## 1. Decompose Conditional(分解条件表达式) +## 1. 分解条件表达式 + +> Decompose Conditional 对于一个复杂的条件语句,可以从 if、then、else 三个段落中分别提炼出独立函数。 @@ -738,7 +788,9 @@ if(notSummer(date)) else charge = summerCharge(quantity); ``` -## 2. Consolidate Conditional Expression(合并条件表达式) +## 2. 合并条件表达式 + +> Consolidate Conditional Expression 有一系列条件测试,都得到相同结果。 @@ -759,7 +811,9 @@ double disabilityAmount(){ } ``` -## 3. Consolidate Duplicate Conditional Fragments (合并重复的条件片段) +## 3. 合并重复的条件片段 + +> Consolidate Duplicate Conditional Fragments 在条件表达式的每个分支上有着相同的一段代码。 @@ -784,13 +838,17 @@ if (isSpecialDeal()) { send(); ``` -## 4. Remove Control Flag(移除控制标记) +## 4. 移除控制标记 + +> Remove Control Flag 在一系列布尔表达式中,某个变量带有“控制标记”的作用。 用 break语 句或 return 语句来取代控制标记。 -## 5. Replace Nested Conditional with Guard Clauses (以卫语句取代嵌套条件表达式) +## 5. 以卫语句取代嵌套条件表达式 + +> Replace Nested Conditional with Guard Clauses 如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回,这样的单独检查常常被称为“卫语句”(guard clauses)。 @@ -820,7 +878,9 @@ double getPayAmount() { }; ``` -## 6. Replace Conditional with Polymorphism (以多态取代条件表达式) +## 6. 以多态取代条件表达式 + +> Replace Conditional with Polymorphism 将这个条件表达式的每个分支放进一个子类内的覆写函数中,然后将原始函数声明为抽象函数。需要先使用 Replace Type Code with Subclass 或 Replace Type Code with State/Strategy 来建立继承结果。 @@ -840,7 +900,9 @@ double getSpeed() {

-## 7. Introduce Null Object(引入Null对象) +## 7. 引入Null对象 + +> Introduce Null Object 将 null 值替换为 null 对象。这样做的好处在于,不需要询问对象是否为空,直接调用就行。 @@ -849,7 +911,9 @@ if (customer == null) plan = BillingPlan.basic(); else plan = customer.getPlan(); ``` -## 8. Introduce Assertion(引入断言) +## 8. 引入断言 + +> Introduce Assertion 以断言明确表现某种假设。断言只能用于开发过程中,产品代码中不会有断言。 @@ -869,19 +933,27 @@ double getExpenseLimit() { # 九、简化函数调用 -## 1. Rename Method(函数改名) +## 1. 函数改名 + +> Rename Method 使函数名能解释函数的用途。 -## 2. Add Parameter(添加参数) +## 2. 添加参数 + +> Add Parameter 使函数不需要通过调用获得某个信息。 -## 3. Remove Parameter(移除参数) +## 3. 移除参数 + +> Remove Parameter 与 Add Parameter 相反,改用调用的方式来获得某个信息。 -## 4. Separate Query from Modifier(将查询函数和修改函数分离) +## 4. 将查询函数和修改函数分离 + +> Separate Query from Modifier 某个函数即返回对象状态值,又修改对象状态。 @@ -896,7 +968,9 @@ getTotalOutstanding(); setReadyForSummaries(); ``` -## 5. Parameterize Method(令函数携带参数) +## 5. 令函数携带参数 + +> Parameterize Method 若干函数做了类似的工作,但在函数本体中却包含了不同的值。 @@ -910,7 +984,9 @@ tenPercentRaise(); raise(percentage); ``` -## 6. Replace Parameter with Explicit Methods(以明确函数取代参数) +## 6. 以明确函数取代参数 + +> Replace Parameter with Explicit Methods 有一个函数,完全取决于参数值而采取不同行为。 @@ -939,7 +1015,9 @@ void setWidth(int arg){ } ``` -## 7. Preserve Whole Object(保持对象完整) +## 7. 保持对象完整 + +> Preserve Whole Object 从某个对象中取出若干值,将它们作为某一次函数调用时的参数。 @@ -955,7 +1033,9 @@ withinPlan = plan.withinRange(low,high); withinPlan = plan.withinRange(daysTempRange()); ``` -## 8. Replace Parameter with Methods(以函数取代参数) +## 8. 以函数取代参数 + +> Replace Parameter with Methods 对象调用某个函数,并将所得结果作为参数,传递给另一个函数。而接受该参数的函数本身也能够调用前一个函数。 @@ -972,7 +1052,9 @@ int basePrice = _quantity * _itemPrice; double finalPrice = discountedPrice (basePrice); ``` -## 9. Introduce Parameter Object(引入参数对象) +## 9. 引入参数对象 + +> Introduce Parameter Object 某些参数总是很自然地同时出现,这些参数就是 Data Clumps。 @@ -980,25 +1062,33 @@ double finalPrice = discountedPrice (basePrice);

-## 10. Remove Setting Method(移除设值函数) +## 10. 移除设值函数 + +> Remove Setting Method 类中的某个字段应该在对象创建时被设值,然后就不再改变。 去掉该字段的所有设值函数,并将该字段设为 final。 -## 11. Hide Method(隐藏函数) +## 11. 隐藏函数 + +> Hide Method 有一个函数,从来没有被其他任何类用到。 将这个函数修改为 private。 -## 12. Replace Constructor with Factory Method (以工厂函数取代构造函数) +## 12. 以工厂函数取代构造函数 + +> Replace Constructor with Factory Method 希望在创建对象时不仅仅是做简单的建构动作。 将构造函数替换为工厂函数。 -## 13. Encapsulate Downcast(封装向下转型) +## 13. 封装向下转型 + +> Encapsulate Downcast 某个函数返回的对象,需要由函数调用者执行向下转型(downcast)。 @@ -1015,13 +1105,17 @@ Reading lastReading(){ } ``` -## 14. Replace Error Code with Exception (以异常取代错误码) +## 14. 以异常取代错误码 + +> Replace Error Code with Exception 某个函数返回一个特定的代码,用以表示某种错误情况。 改用异常,异常将普通程序和错误处理分开,使代码更容易理解。 -## 15. Replace Exception with Test(以测试取代异常) +## 15. 以测试取代异常 + +> Replace Exception with Test 面对一个调用者可以预先检查的条件,你抛出了一个异常。 @@ -1044,19 +1138,25 @@ double getValueForPeriod(int periodNumber) { # 十、处理概括关系 -## 1. Pull Up Field(字段上移) +## 1. 字段上移 + +> Pull Up Field 两个子类拥有相同的字段。 将该字段移至超类。 -## 2. Pull Up Method(函数上移) +## 2. 函数上移 + +> Pull Up Method 有些函数,在各个子类中产生完全相同的结果。 将该函数移至超类。 -## 3. Pull Up Constructor Body(构造函数本体上移) +## 3. 构造函数本体上移 + +> Pull Up Constructor Body 你在各个子类中拥有一些构造函数,它们的本体几乎完全一致。 @@ -1079,55 +1179,73 @@ public Manager(String name, String id, int grade) { } ``` -## 4. Push Down Method(函数下移) +## 4. 函数下移 + +> Push Down Method 超类中的某个函数只与部分子类有关。 将这个函数移到相关的那些子类去。 -## 5. Push Down Field(字段下移) +## 5. 字段下移 + +> Push Down Field 超类中的某个字段只被部分子类用到。 将这个字段移到需要它的那些子类去。 -## 6. Extract Subclass(提炼子类) +## 6. 提炼子类 + +> Extract Subclass 类中的某些特性只被某些实例用到。 新建一个子类,将上面所说的那一部分特性移到子类中。 -## 7. Extract Superclass(提炼超类) +## 7. 提炼超类 + +> Extract Superclass 两个类有相似特性。 为这两个类建立一个超类,将相同特性移至超类。 -## 8. Extract Interface(提炼接口) +## 8. 提炼接口 + +> Extract Interface 若干客户使用类接口中的同一子集,或者两个类的接口有部分相同。 将相同的子集提炼到一个独立接口中。 -## 9. Collapse Hierarchy(折叠继承体系) +## 9. 折叠继承体系 + +> Collapse Hierarchy 超类和子类之间无太大区别。 将它们合为一体。 -## 10. Form Template Method(塑造模板函数) +## 10. 塑造模板函数 + +> Form Template Method 你有一些子类,其中相应的某些函数以相同顺序执行类似的操作,但各个操作的细节上有所不同。 将这些操作分别放进独立函数中,并保持它们都有相同的签名,于是原函数也就变得相同了。然后将原函数上移至超类。(模板方法模式) -## 11. Replace Inheritance with Delegation (以委托取代继承) +## 11. 以委托取代继承 + +> Replace Inheritance with Delegation 某个子类只使用超类接口中的一部分,或是根本不需要继承而来的数据。 在子类中新建一个字段用以保存超类,调整子类函数,令它改而委托超类,然后去掉两者之间的继承关系。 -## 12. Replace Delegation with Inheritance (以继承取代委托) +## 12. 以继承取代委托 + +> Replace Delegation with Inheritance 你在两个类之间使用委托关系,并经常为整个接口编写许多极简单的委托函数。