2011-08-04 25 views
2

我想在幾乎所有的程序中,有時方法不需要一直被調用,而只需要在特定的條件下調用。 它很容易檢查是否必須調用某個方法。一個簡單的if-statment可以做到這一點。最佳實踐:驗證方法調用的條件?

if (value == true) 
{ 
    DoSomething(); 
} 

但是,如果您有許多條件,驗證會變得複雜,代碼變得越來越長。 因此,我使用每次調用 的方法編寫代碼,並且方法本身將檢查並驗證她的代碼是否需要執行。

DoSomething(value); 

...然後...

public void DoSomething(bool value) 
{ 
    if (value == true) 
    { 
    // Do Something here ... 
    } 
} 

現在我有做事的方法有兩種。我不確定哪種方式是正確的。 或者甚至有另一種選擇?

+0

在你的第二個情況下,它實際上像'MayDoSomething',而不是'DoSomething',可以您不會一次驗證,然後處理或處理一組項目。第一個清楚表明什麼時候可以獲得豁免 – V4Vendetta

回答

5

Clean Code — A Handbook of Agile Software Craftsmanship促進不寫方法接受一個布爾參數,因爲每一種方法應該做的一兩件事,只有一兩件事。如果一個方法需要一個布爾參數來決定做什麼,它會自動做兩件事:決定什麼要做,而實際上的東西。該方法應該被重構成兩個獨立的方法來做一些事情和一個方法來決定調用哪兩種方法。

此外,使用value == true評估布爾值是多餘且不必要的。該值本身表示布爾狀態(true/false),不需要再次與true進行比較。 這就是說,最好的做法是使用if (value),而不是if (value == true)(或if ((value == true) == true;這似乎是愚蠢的,但不從if (value == true)的做法不同了)。

0

退房this爲C#不知道爲什麼你需要C++ :)

0

如果該方法可以拋出一個參數/ ArgumentNull例外,那麼你應該在調用該方法之前驗證它。此外,微軟Code Contracts,會告訴你,如果你需要在調用方法之前驗證輸入,對於使用契約的任何代碼(基本斷言用於靜態分析)。

一般規則不是驗證輸入超過必要。如果某些內容無效,則應該拋出異常(C#)或返回錯誤(C++)。由於輸入無效而沒有執行代碼,而沒有說明原因,下一開發人員幾乎無法弄清楚問題所在。

1

但是,如果你有很多條件,驗證會變得複雜,代碼變得越來越長。

如果驗證是複雜的,這意味着邏輯下方是複雜。期望你的代碼像你的邏輯一樣複雜 - 它必須在某個地方,對吧?只要想一想如何以一種乾淨的方式來書寫它。 乾淨的方式並不總是最短的方式。


我建議這個變體:

if (value == true) 
{ 
    DoSomething(); 
} 

爲什麼?這是因爲:

  • 代碼調用DoSomething然後更清楚(*),因爲它明確地示出了當DoSomething邏輯應該被執行,並且當沒有,
  • DoSomething本身取決於以下參數(這使得它更通用和可重用)。

*)是的,「更清晰」實際上在這裏意味着「更長」,但它也意味着「明確」和「自我記錄」。較短的變體實際上試圖隱藏的一些邏輯,這使得代碼明顯少於

0

我建議第二種方式,但我有一些話:

  1. 你並不需要檢查if (value == true),只是檢查if (value)代替。

  2. 返回前,我的意思if (!value) { return; }

+0

請擴展您的答案以包含原因。爲什麼第二種方式是正確的?此外,第1點僅僅是一個無害的語法冗餘,2. imho可以被認爲是一個偏好問題。有一些老派程序員建議,爲了清楚起見,所有塊應該有一個入口點和出口點。 – Kos

+0

@Kos:我改爲推薦。只是我的觀點。 –

2

我覺得這個問題的答案相當明顯 - 除非我錯過了一些東西。適應每種情況。被調用函數應該做它打算做的事情。如果它的意圖是對某些參數進行操作,那麼一定要在函數內部進行檢查。 如果您打算有條件地調用該功能,請在外面檢查。 移動內部檢查只是因爲你可以保存一些額外的驗證是不是一個好主意,我認爲,因爲其他人可能想要調用你的函數,並不知道它是否實際工作給他們的參數。我說,除非內部檢查是必要的,否則留在外面檢查。

編輯: 我只是重新閱讀你的問題...... 您主要有:

void foo(bool actuallyExecuteFoo) 
{ 
    //// 
} 

真的嗎?真?

0

第二種方式需要更多的執行時間,但代碼看起來會更好。你爲什麼不使用宏?

#define DOSOMETHING(value) if (value) {DoSomething();} 

更換所有

if (value == true) {DoSomething(); } 

與宏觀DOSOMETHING(value) 你的目標將得到解決和代碼會更好看