一、Extract Method:提煉方法java
將有些代碼單獨提取出來放入到一個獨立的函數中,並讓函數名稱來解釋該函數的用途。函數
- public void printOwing(double amount) {
- printBanner();
- System.out.println("name:" + name);
- System.out.println("amount:" + amount);
- }
能夠寫成:測試
- public void printOwing(double amount) {
- printBanner();
- printDetails(amount);
- }
-
- /**
- * 描述:打印詳情
- */
- public void printDetails(double amount) {
- System.out.println("name:" + name);
- System.out.println("amount:" + amount);
- }
當看到一個過長的函數或須要註釋才能讓人理解的代碼,應該考慮將這段代碼放到一個單獨的獨立函數中。spa
作法:.net
一、建立一個新的函數,根據函數的意圖來命名。blog
二、將提煉出來的代碼從源函數(source)中拷貝到目標函數(target)中。element
三、仔細檢查提煉出來的代碼,看其中是否引用了做用域僅限於源函數的變量。作用域
四、檢查是否有僅限於被提煉碼的臨時變量,若是有,在目標函數中將它申明爲局部變量。get
五、檢查提煉碼,看是否有任何局部變量的值被改變,若是有一個臨時變量的值被改變,看是否可以將提煉碼處理爲一個查詢,並將結果賦值給臨時變量。it
六、被提煉碼中須要讀取的局部變量,經過參數傳遞給目標函數。
七、處理完全部局部變量後編譯,在源函數中替換目標函數,測試。
例子:
- private String name;
- private Vector<Order> orders = new Vector<Order>();
-
- public void printOwing() {
- Enumeration env = orders.elements();
- double totalAmount = 0.0;
- System.out.println("****************");
- System.out.println("***** test *****");
- System.out.println("****************");
-
- while (env.hasMoreElements()) {
- Order order = (Order) env.nextElement();
- totalAmount += order.getAmout();
- }
-
- System.out.println("name:" + name);
- System.out.println("amount:" + totalAmount);
- }
提取沒有局部變量的函數:
- private void printBanner() {
- System.out.println("****************");
- System.out.println("***** test *****");
- System.out.println("****************");
- }
提取有局部變量的函數:
若是被提煉碼只是須要讀取這些變量的值,並不修改他們,這時候咱們只須要將它做爲一個參數傳遞給目標函數便可,例:
- public void printDetails(double amount) {
- System.out.println("name:" + name);
- System.out.println("amount:" + amount);
- }
若是被提煉碼對局部變量進行賦值:
一、這個變量只是在提煉碼區域中使用,那麼能夠將這個臨時變量的申明式移動到提煉碼中,而後一塊兒提煉出去。
二、若是被提煉碼以外的代碼也使用了這個變量,可分爲:
1)、若是這個變量在被提煉碼以後未再被使用,只須要在目標函數中修改它的值便可。
2)、若是在提煉碼以後還要使用該變量,這個時候就須要讓目標函數返回該變量改變後的值。
一、提取getTotalAmount():
- /**
- * 描述:獲取總帳戶餘額
- */
- public double getTotalAmount() {
- double totalAmount = 0.0;
- Enumeration env = orders.elements();
- while (env.hasMoreElements()) {
- Order order = (Order) env.nextElement();
- totalAmount += order.getAmount();
- }
- return totalAmount;
- }
這個時候的getOwing()可寫成:
- public void printOwing() {
- printBanner();
- double totalAmount = getTotalAmount();
- printDetails(totalAmount);
- }
這裏若是totalAmount初始值不是0,而有一個初值,這個時候就須要將這個初值傳入到目標函數中去。
- public void printOwing(double initAmount) {
- printBanner();
- double totalAmount = initAmount * 1.5;
- totalAmount = getTotalAmount(totalAmount);
- printDetails(totalAmount);
- }
-
- /**
- * 描述:獲取總帳戶餘額
- */
- public double getTotalAmount(double initAmount) {
- double totalAmount = initAmount;
- Enumeration env = orders.elements();
- while (env.hasMoreElements()) {
- Order order = (Order) env.nextElement();
- totalAmount += order.getAmount();
- }
- return totalAmount;
- }
臨時變量每每不少,這個時候能夠考慮Replace Temp with Query(以查詢方法替代臨時變量),若是這樣依舊困難,能夠考慮Replace method with method object(以函數變量替換函數)。