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) を呼び出すことで、ユーザーに確認せずにファイルを保存するかどうかを制御できます。
そのほうがよさそうですか?

4

9 に答える 9

5

これは典型的な単一責任の問題です。

署名が不明な理由は、メソッドが 2 つのことを行っているためです。

2 つのメソッドを作成します。

bool CheckIfTheUserWantsToCancel()
void DoCleanUp()

編集

質問へのコメントと編集に基づいて、3番目の方法を作成します。

void SaveFile()

次に、DoCleanUp は最初に CheckIfTheUserWantsToCancel を呼び出し、キャンセルされない場合は SaveFile を呼び出します。

IMHOこれは、パラメーターfalseを指定したDoCleanUpがユーザーに確認せずにファイルを保存することを覚えようとするよりもはるかに優れていますか、それともその逆でしたか?

于 2009-12-28T19:58:42.510 に答える
3

詳細がなければ、回答1が最高のIMHOだと思います。3 番目は、呼び出すためにより多くのコードが必要になるため、かなり醜いです。

しかし、コードをこれに書き直すことを検討してください

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

これは、単一責任の精神にあるようです。私のコードは、問題を2つのステップに分けています.ユーザーに尋ねることとアクションを実行することです.

于 2009-12-28T19:57:05.827 に答える
1

紛らわしいのは、何もしない可能性があるときに DoSomething() を呼び出すことです。どうですか

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

宣言を見なくても、より冗長ですが、より明確です。

于 2009-12-28T20:06:47.673 に答える
1

私はあなたの1つのバージョンを使用します。

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

前提は、クリーンアップが完了すると true を返すことです。false を返すと、「エラー」状態を示します。int を返すことも理にかなっています。この場合、慣例では通常、0 は成功を表し、それ以外はすべてエラー コードです。

何を決定するかに関係なく、戻り値の意味を文書化してください!

于 2009-12-28T19:56:51.377 に答える
0

ステータス (またはステータス メッセージ) にブール値を使用しないでください。列挙型を作成します。

public Enum CleanupStatus
{
    Ok = 0,
    Cancel
}

このようにして、戻り値が何であるかがより明確になります...さらにステータスを追加する必要がある場合は、追加できます。

(これはすべて Code Complete 2 のものです。まだ読んでいない場合は、読んでください。)

于 2009-12-28T20:31:15.130 に答える
0

基本的に2つのリクエストがあります。外側の要求は、新しいワークスペースを作成することです。内部要求は、現在のワークスペースを保存することです。外側のリクエストが継続する場合は 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();
}
于 2009-12-28T23:29:55.850 に答える
-1

オプション 3 が最も明確になると思います。bool を戻り値の型として使用する場合、それが何に使用されるかはすぐにはわかりません。

于 2009-12-28T19:55:25.543 に答える
-1

普通に一緒に行く

 bool DoCleanUp();  // Returns true if cancel

ただし、ほとんどの場合、呼び出しコードが次のようになっているかどうかによって異なります。

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

また:

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

基本的に、私は自分のテストで a!または 同等の言語を使用する必要がないようにしています。見にくいからです。

私は間違いなく3番をしません。

于 2009-12-28T19:55:37.780 に答える
-1

私は 3 番目のシグネチャを好みますが、それは、(追加のドキュメントなしで) 見ることで、メソッドの機能について詳しく知ることができるからです。ただし、引数は、processCancelled のように、より明示的なものと呼びます。

于 2009-12-28T19:55:44.707 に答える