程序中,某個字段被其所駐類以外的另外一個類更多地用到。在目標類新建一個字段,修改源字段的全部用戶,令它們改用新字段。 java
在類之間移動狀態和行爲,是重構過程當中必不可少的措施。隨着系統的發展,你會發現本身須要新的類,並須要將現有工做責任拖到新類中。 函數
對於一個字段,在其所駐類以外的另外一個類中有更多函數使用了它,咱們就能夠考慮搬移這個字段。上述所謂「使用」多是經過設值/取值函數間接進行的。咱們也可能移動該字段的用戶(某個函數),這取決因而否須要保持接口不受變化。若是函數看上去更適合待在原地,那麼就搬移字段。 測試
1. 若是字段的訪問級是public,使用 Encapsulate Field將它封裝起來。 this
若是有可能移動移動那些頻繁訪問該字段的函數,或若是有許多函數訪問某個字段,先使用SelfEncapsulate Field也許會有幫助。 spa
2.編譯,測試 rest
3.在目標類中創建與源字段相同的字段,並同時創建相應的設值/取值函數。 code
4. 編譯目標類。 對象
5. 決定如何在源對象中引用目標對象。 接口
可能會有一個現成的字段或函數幫助取得目標對象。若是沒有,就看可否輕鬆創建一個這樣的函數。若是仍是不行,就得在源類中新建一個字段來保存目標對象。這多是一個永久性修改,但也可讓它是暫時的,由於後繼的其餘重構項目可能會把這個新建字段去掉。 get
6. 刪除源字段。
7.將全部對元字段的引用替換爲對某個目標函數的調用。
若是須要讀取該變量,就把對源字段的引用替換爲對目標取值函數的調用;若是要對該變量賦值,就把對源字段的引用替換成對設值函數的調用。
若是源字段不是private的,就必須在源類的全部子類中查找源字段的引用點,並進行相應替換。
8. 編譯,測試。
下面是Account類的部分代碼
public class Account { private AccountType type; private double interestRate; double interestForAmountDays( double amount, int days ) { return interestRate * amount * days / 365; } }咱們把表示利率的interestRate搬移到AccountType類去。目前已有數個函數引用了它,interestForAmountDays() 就是其一。下一步咱們要在AccountType中創建interestRate字段以及相應的訪問函數:
public class AccountType { private double interestRate; public double getInterestRate() { return interestRate; } public void setInterestRate( double interestRate ) { this.interestRate = interestRate; } }這時候,能夠編譯新的AccountType類了。
如今咱們須要讓Account類中訪問interestRate字段的函數轉而是用AccountType對象,而後刪除Account類中的interestRate字段。咱們必須刪除源字段,才能保證其訪問函數的確改變了操做對象,編譯器會幫咱們指出未被正確修改的函數。
public class Account { private AccountType type; double interestForAmountDays( double amount, int days ) { return type.getInterestRate() * amount * days / 365; } }
若是有不少函數已經使用了interestRate字段,我應該先運用Self-Encapsulate Field(自我封裝)
public class Account { private AccountType type; private double interestRate; double interestForAmountDays( double amount, int days ) { return getInterestRate() * amount * days / 365; } private void setInterestRate( double arg ) { interestRate = arg; } private double getInterestRate() { return interestRate; } }這樣,在字段搬移以後,我就只須要修改訪問函數;
public class Account { private AccountType type; double interestForAmountDays( double amount, int days ) { return getInterestRate() * amount * days / 365; } private void setInterestRate( double arg ) { type.setInterestRate( arg ); } private double getInterestRate() { return type.getInterestRate(); } }
之後如有必要,咱們能夠修改訪問函數的用戶,讓它們使用新對象。Self-Encapsulate Field是的咱們得以保持小步前進。若是我須要對類作許多處理,保持小步前進時有幫助的。特別值得一提的是:首先使用Self-Encapsulate Field是咱們得以更輕鬆使用Move Method將函數搬移到目標類中。若是待搬移函數引用了字段的訪問函數,那些引用點是無需修改的。