“应取消”的返回值

时间:2009-12-28 19:49:04

标签: method-signature

我有一个方法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.

  4. 更新:至于语言,它是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),您可以控制是否在不询问用户的情况下保存文件 这看起来更好吗?

9 个答案:

答案 0 :(得分:5)

这是一个典型的单一责任问题。

您不确定签名的原因是该方法正在做两件事。

我会创建2个方法:

bool CheckIfTheUserWantsToCancel()
void DoCleanUp()

修改

基于对问题的评论和编辑,我将创建第三种方法:

void SaveFile()

DoCleanUp将首先调用CheckIfTheUserWantsToCancel,如果没有取消则调用SaveFile。

恕我直言这比尝试记住带参数false的DoCleanUp会在不询问用户的情况下保存文件要好得多,还是反过来呢?

答案 1 :(得分:3)

如果没有更多细节,我会说答案1是最好的恕我直言。第三是相当丑陋,因为它需要更多的代码来调用。

但也许可以考虑重写代码

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

这似乎是单一责任的精神。我的代码以某种方式将您的问题分解为两个步骤:询问用户并执行操作。

答案 2 :(得分:1)

我会用你的1版本。

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

假设是,在清理完成后它返回true。返回false表示“错误”状态。返回int甚至可能有意义。在这种情况下,约定通常是0代表成功,其他一切都是错误代码。

无论您决定什么,请记录您的返回值的含义!

答案 3 :(得分:1)

令人困惑的是调用它DoSomething(),它可能什么都不做。 <怎么样

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

更详细但更清晰,即使没有看到声明。

答案 4 :(得分:0)

您不应该对状态(或状态消息)使用布尔值。创建一个枚举:

public Enum CleanupStatus
{
    Ok = 0,
    Cancel
}

通过这种方式可以更清楚地了解返回值是什么......如果您需要添加更多状态,则可以。

(这完全来自Code Complete 2,如果你还没有,你应该阅读它。)

答案 5 :(得分: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();
}

答案 6 :(得分:-1)

我相信选项三最清晰。如果将bool作为返回类型,则无法立即清楚它的用途。

答案 7 :(得分:-1)

我经常跟

一起去
 bool DoCleanUp();  // Returns true if cancel

但主要取决于调用代码是否如下所示:

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

或:

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

基本上我尝试让我的测试不必使用!或语言等效,因为我觉得很难看到。

我绝对不会做第3号。

答案 8 :(得分:-1)

我更喜欢第三个签名,只是因为通过查看它(没有任何额外的文档),我可以更多地了解该方法的作用。我会把这个论点称为更明确的,比如processCancelled。