auto commit

This commit is contained in:
CyC2018 2018-03-20 10:15:37 +08:00
parent 96e3b0ac73
commit 7a686e21ab

View File

@ -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-以继承取代委托)
<!-- GFM-TOC -->
@ -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 有很大好处,但是它的代价是:每当客户要使用受
<div align="center"> <img src="../pics//e024bd7e-fb4e-4239-9451-9a6227f50b00.jpg"/> </div><br>
## 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 去掉类型码。
<div align="center"> <img src="../pics//27c2e0b3-8f95-453d-bedc-6398a8566ce9.jpg"/> </div><br>
## 14. Replace Type Code with Subcalsses以子类取代类型码
## 14. 以子类取代类型码
> Replace Type Code with Subcalsses
有一个不可变的类型码,它会影响类的行为,以子类取代这个类型码。
<div align="center"> <img src="../pics//c41d3977-e0e7-4ee4-93e1-d84f1ae3e20e.jpg"/> </div><br>
## 15. Replace Type Code with State/Strategy (以 State/Strategy 取代类型码)
## 15. 以 State/Strategy 取代类型码
> Replace Type Code with State/Strategy
有一个可变的类型码,它会影响类的行为,以状态对象取代类型码。
@ -714,7 +760,9 @@ public 字段应当改为 private并提供相应的访问函数。
<div align="center"> <img src="../pics//81fd1d6f-a3b2-4160-9a0a-1f7cb50ba440.jpg"/> </div><br>
## 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() {
<div align="center"> <img src="../pics//1c8432c8-2552-457f-b117-1da36c697221.jpg"/> </div><br>
## 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);
<div align="center"> <img src="../pics//08738dd0-ae8e-404a-ba78-a6b1b7d225b3.jpg"/> </div><br>
## 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
你在两个类之间使用委托关系,并经常为整个接口编写许多极简单的委托函数。