2011-08-29 30 views
1

大量的閱讀源代碼時的時候,我看到這樣的事情:我通常不檢查功能輸入是否無效。我錯了嗎?

public void Foo(Bar bar) 
{ 
    if (bar == null) return; 

    bar.DoSomething(); 
} 

我不喜歡這樣,但我似乎是錯誤的,因爲這形式的防禦性編程的被認爲是好的。是不是?例如,爲什麼bar null開頭?是不是像這樣的檢查類似於將繃帶應用於問題而不是解決真正的解決方案?它不僅使功能與其他代碼行復雜化,而且還防止程序員看到潛在的錯誤。

再舉一例:

public void Foo(int x) 
{ 
    int clientX = Math.Max(x, 0); // Ensures x is never negative 
} 

別人看是看防禦性編程,但我看到了未來的錯誤,當一個程序員無意中傳遞一個負值,程序突然爆發,沒有人知道爲什麼,因爲這一點點的邏輯吞噬了可能暴露的例外。

現在,請不要混淆檢查,如果用戶輸入有效的對我要求什麼,我在這裏。顯然用戶輸入應該被檢查。我所要求的只涉及不與用戶或他或她的輸入交互的代碼。

+3

防守性編碼就像是防守性的駕駛 - 因爲你不相信自己的能力,所以你不會開車防守,因爲你不相信其他車手。 – Tim

+0

另外,您必須絕對確定在任何情況下,錯誤都不會導致Bar爲空(創建Bar時內存不足?)。 – grimmig

+3

@Tim,很好地說,但即使在我個人的項目中,我也是在防守編碼,因爲我也不相信自己。 – JBSnorro

回答

2

int clientX = Math.Max(x, 0);不是防禦式編程 - 它被僞裝潛在的問題!

防禦性編程是

if (x < 0) 
    throw new Exception ("whatever"); // or return false or... 

和防禦性編程絕對推薦...你永遠不知道這個代碼將在未來的,所以你要確保它處理任何適當即被稱爲事情是不能處理,必須儘可能早地過濾掉,(由一個有意義的異常例如)調用者必須是「通知」 ......

0

喜歡的東西,

int clientX = Math.Max(x, 0) 

可能在某些情況下非常糟糕的影響,如果你得到x軸負方向,因爲在其他地方節目的故障只是假設,這會導致錯誤傳播。我寧願建議你記錄並在發生不利情況時拋出一個異常(一些特定於業務邏輯的特殊類型)。

1

您檢查空值,因爲試圖有一個空的對象進行操作,將觸發異常。 「沒有」不能做「某事」。你像這樣的代碼,因爲你可以永遠知道時間的100%是什麼狀態你的應用程序將是英寸

話雖這麼說,有編碼反對無效狀態的好壞的方式,以及這些例子你給出的方式並不完全「好」,雖然很難說出什麼時候脫離了上下文。

1

很多時候你可能正在構建一個組件,這個組件將被不同的應用程序使用,輸入由不同的程序員用不同的編碼風格提供,有些可能不會對傳入你的組件/方法的數據進行全面驗證,所以防禦無論組件用戶做什麼,在這種情況下進行編程都會是一件好事。

PS:有一兩件事,通常你不會只從方法返回與上面的表現,你會拋出一個適當的異常,也許一個InvalidArgumentException或類似的東西。

1

也許你看到更多的時候:

public void Foo(Bar bar) 
{ 
    if (bar == null) throw new ArgumentNullException("bar"); 

    bar.DoSomething(); 
} 

這樣,如果某人確實提供了一個null值作爲參數(可能是其他方法的結果),那麼您在代碼中看不到NullReferenceException「somewhere」,但卻是一個異常,它更清楚地說明問題。

1

簡單地返回無效輸入類似於我認爲的無聲嘗試/捕獲。 我仍然驗證從其他代碼段進入我的函數的數據,但是當我遇到無效輸入時總是拋出一個適當的異常。

相關問題