《重構——改善既有代碼》
Motivation
出現依戀情節或者職責不清,應將行為移動到正確的類中。
Mechanics
1 檢查源函數中所使用一切特性(包括field和函數)
2 檢查子類和父類是否也定義了該函數
3 先委託,然後根據實際情況,決定是否將對源函數的調用替換為對目標函數的調用。
Eclipse refactor菜單下直接有Move 選項,可以直接使用該選項完成Move Method重構。但實際應用中,還是有一些細緻的不同,下面詳細說明:
預設情形:[Move] method, 必須要求源類中必須以目標類對象為成員變數,否則找不到目標對象。另外,移動後,預設總是以源類對象作為函數參數。
特殊情形1:目標類是源類的內部類,實際使用copy代碼的方法。
特殊情形2:目標類中成員中已經有源類的對象,實際使用[Move] + [Rename] + [Change Method Signature]的方法
特殊情形3:有時候,只需要將源類的一個成員變數作為函數參數傳入,而沒有必要傳入整個源類對象。實際使用[ExtractLocal Variable] + [Introduce Parameter] / [Extract Method] + [Move],
也可以使用[ExtractLocal Variable] + [Extract Method] + [Inline] + [Move]
double bankCharge(Account account) {double result = 4.5;if (account._daysOverdrawn > 0)result += account.overdraftCharge();return result;}
// 1. 對需要move的函數中的成員變數,應用[Extract Local Variable]替換為局部變數,同時必然會增加“localVariable = _field”這樣一句指派陳述式。
publicclass Account {
double overdraftCharge() {
finalintdaysOverdrawn =_daysOverdrawn;
if (_type.isPremium()) {
double result = 10;
if (daysOverdrawn> 7)
result += (daysOverdrawn - 7) * 0.85;
return result;
} else
returndaysOverdrawn* 1.75;
}
// 2. 對上面新增的指派陳述式"final int daysOverdrawn = _daysOverdrawn;",選中field " _daysOverdrawn",應用Introduce Parmeter,將該field作為函數參數傳入。
public class Account {
double overdraftCharge(int dayOverdrawn) {
final
int
daysOverdrawn =
_daysOverdrawn;
final int daysOverdrawn = dayOverdrawn;
if (
_type.isPremium()){
// 3. 刪除該指派陳述式”localVariable = _field”。
public class Account {
double overdraftCharge(int dayOverdrawn) {
final
int
daysOverdrawn =
dayOverdrawn;
if (
_type.isPremium()){
=========================================================================================
還有一種更通用的調整方法,其核心思想是將舊方法介面委託給新方法,然後應用內聯將所有舊方法替換為新方法,最後move。
第一步同上,第二步改為使用[Extract Method],將 指派陳述式"final int daysOverdrawn = _daysOverdrawn;"以下的部分抽取為新的函數,函數名與目標函數相同,都是overdraftCharge.
public classAccount {
double overdraftCharge() {
final int daysOverdrawn = _daysOverdrawn;
return overdraftCharge(daysOverdrawn);
}
private double overdraftCharge(final int daysOverdrawn) {
if (_type.isPremium()){
double result = 10;
if (daysOverdrawn > 7)
result +=(daysOverdrawn - 7) * 0.85;
return result;
} else
return daysOverdrawn * 1.75;
}
//3. 使用[Inline]替換掉目標函數
先對daysOverdrawn應用[Inline]
double overdraftCharge() {
final
int
daysOverdrawn =
_daysOverdrawn;
return overdraftCharge(_daysOverdrawn);
}
再對overdraftCharge() 應用[Inline]
double
overdraftCharge() {
return
overdraftCharge(
_daysOverdrawn
);
}
原來調用overdraftCharge()的地方自動調整為 overdraftCharge(_daysOverdrawn)
result += overdraftCharge(); --> result += overdraftCharge(_daysOverdrawn);
over
以上完整源碼可以在here下載