2015-10-22 38 views
6

我是很困惑如何確定一個單一的方法有一個責任正在做就像從書中下面的代碼清潔守則瞭解單一職責原則

public Money calculatePay(Employee e) throws InvalidEmployeeType { 
     switch (e.type) { 
      case COMMISSIONED: 
       return calculateCommissionedPay(e); 
      case HOURLY: 
       return calculateHourlyPay(e); 
      case SALARIED: 
       return calculateSalariedPay(e); 
      default: 
       throw new InvalidEmployeeType(e.type); 
     } 
    } 

由於筆者在此代碼段說明:「...... 顯然不止一件事 第三,它違反了單一責任原則(SRP),因爲它有一個以上的 原因」。首先看一下代碼,我在想如果這個方法違反了SRP,因爲如果代碼發生了變化,那麼只有在添加員工類型時纔會使用switch語句,但是當我嘗試瞭解方法時進一步,我提出了一個爲什麼違反所述原則的假設。

我的假設是,由於該方法的名稱是calculatePay(Employee e),那麼此方法的唯一責任是支付計算,因爲該方法的名稱顯示,但由於該方法內部存在一個開關,用於過濾此類型的員工過濾現在是不同的或另一種責任,因此違反了SRP。我不知道我是否正確。

回答

5

「......顯然做多件事情。第三,它違反了單 職責原則(SRP),因爲有多個原因 它改變。」

有你的答案。每當添加新的Employee.Type時,該方法將不得不改變。另外,每個Employee.Type的計算也可能改變。

一個更好的解決方案是爲Employee創建一個Abstract Factory,並且Employee的每個派生自己實現CalculatePay。這樣,當計算更改或添加新的Employee.Type時,只需要更改一個類。

下面是從更細緻的解釋清潔守則另一個提取物 -

的解決了這個問題(見列表3-5)是埋葬開關 聲明一個抽象工廠的地下室, 9,絕對不會讓任何人看到它。工廠將使用switch語句創建 Employee的衍生工具的適當實例,並且諸如calculatePay,isPayday和deliverPay等各種函數將通過Employee接口以多態方式分配到多個 函數。我一般 規則switch語句是,他們可以容忍的,如果他們 只出現一次,用於創建多態對象

+0

謝謝你的投入,我想作爲對'另外,每個Employee.Type的計算也可能改變。僱員的計算如何影響該方法?由於每種類型只是調用一種方法來執行計算,我認爲,並且根據您的答案和本書給出的說明,我是否可以假設我對於如何理解該原則的假設是正確的? – anathema

+1

[單責任責任人](https://en.wikipedia.org/wiki/Single_responsibility_principle)應該在類的上下文中看到,而不一定在方法級上。這就是爲什麼我說如果任何計算更改,您需要更新此類。如果您將此方法移至Employee的衍生工具,那麼如果計算需要更改,則只有該類必須更改。如果例如,也可以是@anathema,例如 –

+0

@anathema。我們想要計算小時支付的不同(假設週末工作對薪水有影響),那麼我們可能會更改calculateHourlyPay函數簽名(添加布爾標誌或日期時間),因此calculatePay函數也需要更改。 –

3

我一般在類級別應用SRP。它可以防止班級變得太大並承擔太多角色。

我把'責任'視爲概念。因此,我認爲你的方法只有一個責任:計算工資。

我試圖效仿谷歌在此的guidelines,尋找這些警告跡象表明你從SRP徘徊遠:

  • 總結一下類不包括單詞「和」。
  • 對於新團隊成員或缺乏經驗的開發人員 來說,課程將很難進行閱讀並快速「獲取」。
  • 類具有僅用於某些方法的字段。
  • 類具有僅對參數進行操作的靜態方法。

在另一方面,然而,你的代碼包含提示你可能會徘徊在OCP遠switch語句...