2012-08-10 147 views
4

我與我的朋友有爭議。setter驗證:哪種方法更好?

他說我這個代碼:

method SetBalance(balance) { 
    if (balance > 0) { 
     this.balance = balance; 
     return true; 
    } 
    return false; 
} 

是更好,然後這樣的:

method SetBalance(balance) { 
    if (balance < 0) { 
     throw new InvalidArgumentException("Balance couldn't be negative") 
    } 
    this.balance = balance; 
} 

我的問題是: 「哪種方法進行驗證更好」爲什麼?

謝謝。

+0

爲什麼不能平衡爲0? – Eimantas 2012-08-10 08:07:29

+0

即使回報比較好,我會用比bool更具描述性的東西。 – Giedrius 2012-08-10 08:19:07

+0

Eimantas,它是例如。 – 2012-08-10 08:21:28

回答

6

啊。返回狀態與異常。

我更喜歡拋出異常,因爲你不能真正忽略異常。該程序崩潰,或者你必須明確地捕捉並處理它。

您可以忽略返回狀態。

此外,這不是現代編程中存在異常的原因嗎?要處理好,例外(餘額< = 0,不應該發生的事情)。

+0

我很肯定,前一段時間有一個說法,拋出異常是昂貴的,所以如果有可能避免異常,可以使用別的東西,但我想現在不是這樣了 – Giedrius 2012-08-10 08:17:40

+0

@Giedrus是非常知名的口頭禪。作者在這裏詢問了關於糾正編碼錯誤的問題。異常非常有意義 – 2012-08-10 08:19:04

+0

嗯,他提到驗證和驗證通常用於驗證輸入數據,而不是代碼邏輯。 – Giedrius 2012-08-10 09:11:56

1

在setter的情況下,開發人員將永遠不會期望這些方法的返回值,因爲他們認爲這將無論如何將負責設置值。
萬一,如果有例外,那麼這將有助於理解某些事情真的是錯誤的,並再次關注代碼。
而不是runtime exception,您最好定義自己的異常,如InvalidBalanceException,並指定此方法將在簽名本身中引發此異常。這避免了測試階段的意外,並在開發階段自行決定業務邏輯。

1

返回值很容易被忽略。在這裏你有明確的編碼錯誤,所以大聲崩潰。我甚至會暫停/分段/停止程序 - 異常仍可能被捕獲。我們生活在「理想世界」,但想象一下我們不那麼幸運的同事 - 他們可能會因爲無法處理根本原因而插嘴錯誤信號設施(插入更復雜的錯誤情景)。當你不給客戶方式做錯事情的方式時,編碼變得容易得多。

0

除了已經給出的答案之外,在名爲「setFoo」的函數中返回一個布爾值是非常具有誤導性的。如果你翻譯一個布爾值,你會得到yes/no。因此,一個返回oop中布爾值的函數應該是可讀的,這個問題會給出是/否的答案。 isBalanceSet。

在與同事討論時,我們認爲普通setter的唯一有效返回值就是fluent接口的類本身。

關於你的問題拋出異常是更好的解決方案,如果類實際上驗證其性質本身;)

0

我個人的看法:這兩種方法都有其用途。這取決於情況出現的原因,是否可以防止,客戶可以做些什麼來阻止它。

服務器:

method SetBalance(int balance) 
{ 
    // do something only if balance >= 0 
} 

客戶:

myServer.SetBalance(balance); 

案例1: 這種情況只出現錯誤的,因爲地方(在服務器或客戶端)。拋出異常。讓責任方修復它的代碼。

案例2: 從某些外部依賴項收到錯誤的輸入。客戶可以輕鬆檢查前提條件。拋出異常,讓客戶修復它的代碼,如果她不滿意。

if(balance>0) 
    myServer.SetBalance(balance); 
else 
    //take appropriate action. 

情況3: 壞輸入是從一些外部依賴接收。客戶無法輕易檢查前提條件。例如:它需要客戶端解析一個字符串,這是服務器的工作。在這裏,它是有道理的,服務器應當返回成功:

bool succeeded = myServer.SetBalance(balance); 
if(!succeeded) 
    //take appropriate action. 

寫我的回答下來後,我發現這一切歸結爲:客戶端不應該使用try-catch來調用該方法的setBalance 。(無論它是一個錯誤,所以不要捕獲異常,或檢查自己的前提下,或檢查返回值)

下面是相關的主題良好的閱讀:http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx

編輯: 喬喬說得很好。重命名方法TrySetBalance()如果有可能失敗。

0

異常處理是處理OOP中的錯誤的方法,無論是運行時錯誤還是邏輯錯誤。證明異常處理的一個參數是,如果使用錯誤代碼,函數的客戶端可能會忘記檢查導致潛在錯誤的錯誤代碼,這些錯誤可能不容易找到。而如果使用異常處理,即使它未被捕獲,它也會傳播,直到它被處理。所以,OOP純粹主義者總是建議使用異常處理。