代码之家  ›  专栏  ›  技术社区  ›  AZ.

“应取消”的返回值

  •  0
  • AZ.  · 技术社区  · 16 年前

    我有一个方法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语言。

    更新2:现在假设我必须在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 save file),您可以控制是否在不询问用户的情况下保存文件。
    看起来更好吗?

    9 回复  |  直到 16 年前
        1
  •  5
  •   Shiraz Bhaiji    16 年前

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

    你对签名不确定的原因是这个方法做了两件事。

    我将创建两种方法:

    bool CheckIfTheUserWantsToCancel()
    void DoCleanUp()
    

    编辑

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

    void SaveFile()
    

    然后,docleanup将首先调用checkif theuserwantsocancel,如果不取消,则调用savefile。

    imho这比试图记住参数为false的docleanup将在不询问用户的情况下保存文件要好得多,还是相反?

        2
  •  3
  •   Michal Sznajder    16 年前

    如果没有更多的细节,我会说答案1是最好的imho。第三个相当难看,因为它需要更多的代码来调用。

    但也许可以考虑重写代码

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

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

        3
  •  1
  •   Peter Schuetze    16 年前

    我会用你的1版。

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

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

    不管你决定什么,记录你的返回值是什么意思!

        4
  •  1
  •   egrunin    16 年前

    令人困惑的一点是调用它dosomething(),因为它可能不做任何事情。怎么样

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

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

        5
  •  0
  •   Martin    16 年前

    对于状态(或状态消息),不应使用布尔值。创建枚举:

    public Enum CleanupStatus
    {
        Ok = 0,
        Cancel
    }
    

    这样就更清楚了返回值是什么…如果你需要添加更多的状态,你可以。

    (这都来自代码完成2,如果您还没有阅读,应该阅读它。)

        6
  •  0
  •   jmucchiello    16 年前

    您基本上有两个请求。外部请求是创建一个新的工作区。内部请求是保存当前工作区。如果外部请求继续,则返回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();
    }
    
        7
  •  -1
  •   ChaosPandion    16 年前

    我认为第三种方案最为明确。当您将bool作为返回类型时,不能立即清楚它的用途。

        8
  •  -1
  •   James Keesey    16 年前

    我通常和

     bool DoCleanUp();  // Returns true if cancel
    

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

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

    或者:

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

    基本上我试着让我的测试不必使用 ! 或者像我觉得很难看到的语言。

    我绝对不会选第三名。

        9
  •  -1
  •   Tola Odejayi    16 年前

    我更喜欢第三个签名,因为通过查看它(没有任何额外的文档),我可以了解更多关于该方法的功能。我会把这个论点称为更明确的东西,比如processcancelled。

    推荐文章