“应该取消”的返回值

发布于 2024-08-16 02:20:18 字数 979 浏览 3 评论 0原文

我有一个方法 DoCleanUp(),它将要求用户继续,然后清除当前工作区。如果用户选择取消此过程,它将返回。

我的问题是,哪个签名最能表明“取消”?

  1. bool DoCleanUp(); // 返回 false 表示已取消。

  2. bool DoCleanUp(); // 返回true表示应该取消该方法。

  3. void DoCleanUp(bool&cancel); // 检查参数“cancel”以查看此方法是否被取消。

更新: 至于语言,是 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),您可以控制是否保存文件,而无需询问用户。
这样看起来更好吗?

I have a method DoCleanUp(), which will ask user to proceed and then clear current workspace. It will return if user choose to cancel this process.

My question is, which signature is best to indicate a "cancel"?

  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.

UPDATE: As for the language, it's C++\CLI or C#.

UPDATE2: Now suppose I have to save a file in the DoCleanUp method. I'll prompt a dialog ask user whether to save/not save/cancel the file. Based on the answers, here is what I came up:

void DoCleanUp();

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

void DoCleanUp( bool saveFile );

Usage:

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

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

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

Then by calling DoCleanUp(), you know user will have the opportunity to cancel;
By calling DoCleanUp(bool saveFile), you can control whether to save file without asking user.
Is that looks better?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

葬花如无物 2024-08-23 02:20:19

令人困惑的地方是调用它 DoSomething(),而它可能什么也不做。怎么样?

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

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

The confusing bit is the calling it DoSomething(), when it might not do anything. How about

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

More verbose but clearer, even without seeing the declaration.

妞丶爷亲个 2024-08-23 02:20:19

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

public Enum CleanupStatus
{
    Ok = 0,
    Cancel
}

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

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

You should not use a boolean for statuses (or status messages). Create an Enum:

public Enum CleanupStatus
{
    Ok = 0,
    Cancel
}

This way it is more clear what the return value is ... and if you need to add more statuses, you can.

(This is all from Code Complete 2, you should read it if you haven't yet.)

嘿看小鸭子会跑 2024-08-23 02:20:19

基本上你有两个要求。外部请求是创建一个新的工作区。内部请求是保存当前工作空间。如果外部请求继续,您希望返回 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();
}

You have two requests basically. The outer request is to create a new workspace. The inner request is to save the current workspace. You want to return true if the outer request continues and false if the outer request is aborted. The action of the inner request is not important to the outer request and so should be some kind of delegate/functor/closure.

Make a class to genericize this:

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();
}
允世 2024-08-23 02:20:19

我相信选项三给出了最清晰的信息。当您将 bool 作为返回类型时,并不能立即清楚它的用途。

I believe option three gives the most clarity. When you have the bool as a return type it is not immediately clear what it is used for.

時窥 2024-08-23 02:20:19

我通常会选择,

 bool DoCleanUp();  // Returns true if cancel

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

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

或:

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

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

我绝对不会做第三点。

I usually go with

 bool DoCleanUp();  // Returns true if cancel

but mostly it depends on whether the calling code looks like this:

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

or:

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

Basically I try to make my tests not have to use a ! or language equivilent as I find it hard to see.

I definitely would not do number 3.

再浓的妆也掩不了殇 2024-08-23 02:20:19

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

I prefer the third signature, only because by looking at it (without any extra documentation), I can tell more about what the method does. I would call the argument something more explicit, like processCancelled, though.

最好是你 2024-08-23 02:20:18

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

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

我将创建 2 个方法:

bool CheckIfTheUserWantsToCancel()
void DoCleanUp()

编辑

根据对问题的评论和编辑,我将创建第三个方法:

void SaveFile()

DoCleanUp 将首先调用 CheckIfTheUserWantsToCancel,然后如果未取消,将调用 SaveFile。

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

This is a classic single responsibility problem.

The reason that you are unsure about the signature is that the method is doing 2 things.

I would create 2 methods:

bool CheckIfTheUserWantsToCancel()
void DoCleanUp()

EDIT

Based on the comments and edits to the question I would create a 3rd method:

void SaveFile()

The DoCleanUp would then first call CheckIfTheUserWantsToCancel, and then if not cancelled would call SaveFile.

IMHO this is much better than trying to remember that DoCleanUp with parameter false will save the file without asking the user, or was it the other way around?

无戏配角 2024-08-23 02:20:18

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

但也许考虑将代码重写为这

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

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

Without more details I would say answer 1 is the best IMHO. Third is rather ugly since it requires more code for calling.

But maybe consider rewriting code to this

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

This seems to in the spirit of single responsibility. My code somehow breaks your problem into two steps: asking user and performing action.

笑看君怀她人 2024-08-23 02:20:18

我会使用你的 1 版本。

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

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

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

I would use your 1 version.

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

The assumption is, that it returns true when the cleanup is done. Returning false would indicate a 'Error' state. It might even make sense to return an int. In this case the convention usually is that 0 represents success and everything else is an error code.

Regardless of what you decide, document what your return values mean!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文