2009-12-28 42 views
0

我有一個方法DoCleanUp(),它會要求用戶繼續並清除當前工作區。如果用戶選擇取消該過程,它將返回。「應取消」的返回值

我的問題是,哪個簽名最好表示「取消」?

  1. bool DoCleanUp(); // return false to indicate canceled.

  2. bool DoCleanUp(); // return true to indicate this method should be canceled.

  3. void DoCleanUp(bool& cancel); // check parameter 'cancel' to see if this method was canceled.

更新:至於語言,這是C++ \ CLI或C#。

UPDATE2:現在假設我必須在DoCleanUp方法中保存一個文件。我會提示用戶詢問用戶是否保存/不保存/取消文件。根據答案,這裏是我想出了:

void DoCleanUp();

DialogResult AskToSaveFile(); // return yes/no/cancel

void DoCleanUp(bool saveFile);

用法:

void DoCleanUp() 
{ 
    DialogResult result = AskToSaveFile(); 

    if(result == DialogResult::Cancel) return; 

    bool saveFile = (result == DialogResult::Yes) ? true : false; 
    DoCleanUp(saveFile); 
} 

然後通過調用DoCleanUp(),你知道用戶將有機會取消;
通過調用DoCleanUp(bool saveFile),您可以控制是否在不詢問用戶的情況下保存文件。
這看起來更好嗎?

+0

什麼語言嗎?德爾福? C? C++? C#? – 2009-12-28 19:50:43

+0

獨立語言...這是直接從代碼完成,閱讀我的答案下面。 – Martin 2009-12-28 20:32:25

回答

5

這是一個經典的單一責任問題。

你不確定簽名的原因是該方法做了2件事。根據該意見

bool CheckIfTheUserWantsToCancel() 
void DoCleanUp() 

編輯

和編輯,以我想創建一個3方法問題:

我將創建2種方法

void SaveFile() 

的DoCleanUp會然後首先調用CheckIfTheUserWantsToCancel,然後如果不取消則調用SaveFile。

恕我直言,這比試圖記住具有參數false的DoCleanUp會在不詢問用戶的情況下保存文件好得多,還是以其他方式呢?

+0

這是一個很好的觀點,但通常這種方法需要重複大量的代碼。 – nickf 2009-12-28 20:12:30

+0

@nickf:在顯示對話框和清理工作區之間會複製多少代碼?這是兩個完全不同的任務。 – Chuck 2009-12-28 20:34:41

+0

@Chuck:他在說可能會有很多地方以這種方式調用這兩個函數。更好的是將它分解成這些函數(或者,實際上,只是對第一個函數使用諸如'ShowDialog'之類的東西)並且具有另一個調用它們的函數。 – 2009-12-28 21:06:14

-1

我相信選項三是最清晰的。當你將bool作爲返回類型時,它不會立即清楚它用於什麼。

-1

我通常

bool DoCleanUp(); // Returns true if cancel 

去,但主要是這取決於調用代碼是否看起來是這樣的:

if (DoCleanUp()) { 
    // Do cancel up code 
} 

或:

if (DoCleanUp()) { 
    // Do non-cancel post clean up code 
} 

基本上,我儘量讓我的測試不必使用!或語言equivilent,因爲我覺得很難看。

我絕對不會做數3

-1

我更喜歡第三個簽名,只因爲看它(無任何額外的文檔),我可以告訴更多的方法做什麼。不過,我會更加明確地調用參數,比如processCancelled。

1

我會用你的1版本。

bool DoCleanUp(); // return false to indicate canceled. 

假設是,它在清理完成時返回true。返回錯誤將指示「錯誤」狀態。它甚至有可能返回一個int。在這種情況下,約定通常是0表示成功,其他所有內容都是錯誤代碼。

無論您決定什麼,記錄您的返回值意味着什麼!

3

沒有更多的細節我會說答案1是最好的恕我直言。第三是相當醜陋,因爲它需要更多的調用代碼。

但也許考慮重寫代碼,這

void CleanUp() { 
    switch (AskUser()) { 
    case ButtonOk: CleanUpDesk(); break; 
    case ButtonNo: break; 
    default: 
    case ButtonCancel: CancelCleanUpDesk(); break; 
    } 
} 

這似乎在單一負責的精神。我的代碼以某種方式將問題分解爲兩個步驟:詢問用戶並執行操作。

1

令人困惑的是它調用它DoSomething(),當它可能什麼都不做時。怎麼樣

if (QueryCleanup())  // boolean 
    DoCleanup();  // void 

更詳細,但更清晰,即使沒有看到聲明。

0

不應該爲狀態(或狀態消息)使用布爾值。創建一個枚舉:

public Enum CleanupStatus 
{ 
    Ok = 0, 
    Cancel 
} 

這種方式更明確的返回值是什麼...如果你需要添加更多的狀態,就可以了。

(這是所有的代碼完成2,如果你還沒有,你應該看它。)

+0

「二元」枚舉和布爾之間的爭論是長期存在的,並且可能暫時保持不變。 – 2009-12-28 21:09:30

0

你有兩種基本的要求。外部請求是創建一個新的工作區。內部請求是保存當前工作區。如果外部請求繼續,您希望返回true,如果外部請求被中止,則返回false。內部請求的動作對外部請求並不重要,所以應該是某種委託/函子/閉包。

做一個類泛化這樣的:

class YesNoCancel { 
    string question; // question to ask the user about the inner state 
    delegate doit; // function to call to 
    delegate dontdoit; 
public: 
    YesNoCancel(string question, delegate doit, delegate dontdoit = null) {...} 

    bool run() { 
    switch (AskUser(question)) { 
    case ANSWER_YES: doit(); return true; 
    case ANSWER_NO: return true; 
    case ANSWER_CANCEL: if (dontdoit) dontdoit(); return false; 
}; 

//usage 

void NewWorkspace() { 
    if (m_workspace) { 
     YesNoCancel ync("Save current workspace?", saveworkspace); 
     if (!ync.run()) return; 
    } 
    // new workspace code 
} 

void CloseApp() { 
    YesNoCancel ync("Save current workspace?", saveworkspace); 
    if (ync.run()) ExitApplication(); 
}