2008年1月30日 星期三

重構-Making Method Calls Simpler

Refactor
(圖片來自: http://sourcemaking.com/)
以下為學習 Making Method Calls Simpler 的筆記.

Add Parameter

若方法需要呼叫方的資訊,就在方法介面加上參數,讓呼叫方傳入參數.

Encapsulate Downcast

方法若回傳需要轉型的結果,請在方法內直接轉型好再回傳.

優點: 其他使用到此方法的部份不用在做轉型.

Hide Method

若 public 方法沒有被其它 Class 使用,將 public 改成 private .

Introduce Parameter Object

若傳入的參數在概念上可群聚在一起,將這些參數包裝成一個新的物件.

/* 利用身高體重算出的 BMI 來決定是否健康. */
public boolean isHealthy(int height, int weight)
{
  int bmi = weight / (height * height);

  if (18 < bmi && bmi < 24)
  {
    return true;
  }
  else
  {
    return false;
  }
}

Class BodyMassIndex
{
  /* 建構子. */
  public BodyMassIndex(int height, int weight) // 兩個傳入參數.
  ...

  /* 回傳 BMI 的值.
   * 計算方式被封裝起來,可重覆利用. */
  public int getValue()
  {
    return (weight / (height * height));
  }

}

/* 利用 Parameter Object . */
public boolean isHealthy(BodyMassIndex bmi) // 簡化成一個物件.
{
  if (18 < bmi.getValue() && bmi.getValue() < 24)
  {
    return true;
  }
  else
  {
    return false;
  }
}

優點: 解決參數過多不易閱讀的問題. 若群聚參數產生的物件能提供一個合適的地方,以儲存跟參數有關的行為.

Parameterize Method

許多方法都在做類似的工作,差別只在於數值的不同. 合併成一個方法,並將不同的數值部份改成方法的傳入參數.

有點難解釋直接舉例:

/* 打九折. */
public int tenPercentageDiscount(int price)
{
}

/* 打八折. */
public int twentyPercentageDiscount(int price)
{
}

/* 合併成一個方法,折數由傳入參數來決定. */
public int dicount(int price, int percentage)
{
}

優點: 減少重覆的程式碼. 支援的方式也從原本需新增加方法(重覆程式碼)變成根據傳入參數來決定.

Preserve Whole Object

某個方法傳入的參數都是來自於同一個物件,再考慮過耦合度的情況下,直接將傳如參數改成該物件.

int height = jack.getHeight();
int weight = jack.getWeight();
int bmi = caculateBmi(height, weight);

/* 修改參數改成直接傳入 People 物件. */
int bmi = caculateBmi(jack);

/* 傳入參數由原本的兩個 int 改成 一個 People 物件. */
public int caculateBmi(People people) // 和 People 產生關聯.
{
  /* 只要 People 物件有的成員都可以使用,且不用修改傳入參數. */
  int height = people.getHeight();
  int weight = people.getWeight();
  ...
}

優點: 易閱讀. 彈性高.

缺點: 增加耦合度.

Remove Parameter

移除方法中沒用到的傳入參數.

優點: 表達出程式碼真正要傳達的訊息(無用的參數帶來造成誤會的訊息).

Remove Setting Method

一個只在建立物件時確定且以後不會再變化的成員變數,移除該成員變數的 setter().

優點: 表達該成員變數的真正意圖 - 建立後就不允許修改.

Rename Method

當方法名稱無法表示出其意圖時 - 重新命名.

優點: 好的命名帶來正確的意圖.

Replace Constructor with Factory Method

當產生物件時不單單只是單純的建構,而想要有更複雜的建構方式時 - 使用工廠方式.

Replace Error Code with Exception

使用 Exception 取代 Error Code.

優點: 易閱讀. Exception 將 問題程序 從 正常程序 分離出來.

Replace Exception with Test

Exception 該用在例外的行為上,不要用 Exception 來做條件判斷.

Replace Parameter with Explicit Methods

方法根據傳入的參數執行不同的區段 - 抽取出每個區段建立各自的方法.

Replace Parameter with Method

方法傳入的參數為本身可自行取得 - 移除參數,由該方法自行取得.

int percent = getPercent();
int finalPrice = discount(1000, percent);
...

public int discount(int price, int percent)
{
  ...
}

int finalPrice = discount(1000);
...

public int discount(int price) // 減少了傳入的參數數量.
{
  int percent = getPercent(); // 由 discount() 自己取得打折的折數.
  ...
}

優點: 減少傳入參數數目,增加閱讀性.

Separate Query from Modifier

若方法回傳數值並且修改本身物件的狀態 - 將其分成兩個方法: "查尋" 和 "修改".

優點: 避免不在預期內的 side effect .

0 則回應:

Related Posts Plugin for WordPress, Blogger...