2009-05-28 63 views
3

在編寫小函數時,我經常會遇到這樣的情況:某些函數只能傳遞給不同的小函數來實現其功能。何時檢查功能/方法參數?

例如(C#語法-ish):

public void FunctionA(object param) 
{ 
    DoA(param); 
    DoB(param); 
    DoC(param); 
    // etc. 
} 

private void DoA(object param) 
{ 
    DoD(param); 
} 

private void DoD(object param) 
{ 
    // Error if param == null 
    param.DoX(); 
} 

所以參數沒有被調用的函數內使用,但「地方」在那做的工作的小功能深處。

那麼最好檢查一下我的param-Object是否爲空?

當泛函檢查:

臨: -there是通過採用另外的方法,其最終會做什麼,因爲對象是空的開銷。

Con: - 我的語法上美妙的FunctionA被醜陋的驗證代碼弄髒了。

當檢查僅當使用PARAM對象:

臨: - 我的語法精彩泛函保持一個快樂閱讀:)

缺點: -there將通過開銷調用該方法會不做任何事情,因爲參數對象爲空。 - 進一步的缺點我目前沒有考慮。

+0

這被稱爲咖喱功能 - 雖然有點過於簡化。 http://en.wikipedia.org/wiki/Currying – 2012-08-10 08:20:43

回答

4

除非你認爲這個值在絕大多數時候可能爲空,否則我會在DoD()中進行驗證。如果你把它放在FunctionA()中,那麼當你決定FunctionB()也需要使用DoD()時,你將不得不重複驗證代碼。對我而言,額外的開銷是值得不必重複自己的。

6

總是儘可能將它放在調用堆棧的最下方,以便如果您稍後重構代碼,並且別的方法調用了DoA以外的其他方法,則您將檢查到位並且不必重新進行參數檢查。在大多數情況下,一個小的空檢查以及可能的幾個額外的方法調用的開銷將變得微不足道,而多做幾次檢查並不是你應該擔心的事情。

+0

絕大多數情況下都是正確的。如果確實有耗時的操作,最終可能會失敗,那麼您可以嘗試避免調用DoA,DoB知道DoC會因爲DoD而失敗。但是這已經是優化了,我仍然可以在國防部進行檢查,但是也有在FunctionA中檢查。 – van 2009-05-28 13:22:13

1

作爲一個指導方針,我養成了這樣一個習慣:檢查該方法使用的每個參數,甚至包括我自己的私有變量。因此,我只會在國防部方法中檢查零。

你可能想看看Bertrand Meyers Design By Contract曼陀羅。

0

經常檢查:)從編碼庫,用於嵌入式系統的深腸子即將一切,這是方法我會使用:

public void FunctionA(object param) 
{ 
    assert(param != null && param.canDoX()); 
    DoA(param); 
    DoB(param); 
    DoC(param); 
    // etc. 
} 

private void DoA(object param) 
{ 
    assert(param != null && param.canDoX()); 
    DoD(param); 
} 

private void DoD(object param) 
{ 
    assert(param != null && param.canDoX()); 
    if (param != null) 
     param.DoX(); 
    else 
     // Signal error, for instance by throwing a runtime exception 
     // This error-handling is then verified by a unit test that 
     // uses a release build of the code. 
} 

要取消這個雜亂,顯而易見的解決辦法是打出來的驗證到一個單獨的驗證器功能。使用C風格的預處理器,或只是堅持斷言,從發佈版本中排除「偏執」驗證應該是微不足道的。

1

提前失敗。除非部分結果比根本沒有結果更可取,否則只要代碼能夠檢測到存在問題,就應該停止執行。爲什麼當下遊的結果是一個無效或缺少的參數時,代碼會通過幾種方法運行?

如果可能單獨調用下游方法,那麼驗證可以通過調用ca來進行通用驗證,如前所述。

0

調用者的責任是傳遞一個有效的參數。在這種情況下:

if(param != null) 
{ 
    FunctionA(param); 
}