2

コマンドパターンに従うクラスがあります。Execute と、Execute を呼び出すかどうかをチェックする CanExecute の 2 つのメソッドがあります (これらはICommandから派生します)。CanExecute は、必要なすべてのサービスが実行されていること、バージョンが正しいことなどを確認するいくつかのメソッドを呼び出します。

CanExecute が呼び出された後、失敗して false が返されることがあります。その理由を知る必要があります。バージョン、サービス、不足しているファイルなどが原因でしょうか。

問題が何であるかを知るための最良の戦略は何ですか

1 つのオプションは、必要な条件が失敗するたびに、メッセージ フィールドにエラーを説明する例外をスローすることです。ただし、失敗する可能性が予想されるため、通常の制御フローに例外を使用しないでください。だから私は本当にわかりません。

ありがとうございました。

4

3 に答える 3

1

更新:フィードバックに基づいて作り直されました。

UIにはCanExecute()がfalseを返す理由が必要なため、次の2つのことが頭に浮かびます。

オプション1:列挙可能なメッセージプロパティをコマンドインターフェイスに追加し、CanExecute()の呼び出し中に必要に応じて入力します。その後、UIは必要に応じてプロパティに問い合わせることができます。このルートを使用する場合は、CanExecute()を呼び出すたびにプロパティの内容をクリアして、状態を見失わないようにしてください。

public interface ICommand
{
    IEnumerable<string> Messages { get; }
    bool CanExecute();
    void Execute();
}

public class SomeCommand : ICommand
{
    public IEnumerable<string> Messages { get; private set; }

    public bool CanExecute()
    {
        var messages = new List<string>();

        var canExecute = true;

        if (SomeCondition)
        {
            canExecute = false;
            messages.Add("Some reason");
        }

        if (AnotherCondition)
        {
            canExecute = false;
            messages.Add("Another reason");
        }

        Messages = messages;

        return canExecute;
    }

    public void Execute() { }
}

オプション2: CanExecute()に、boolと列挙可能なmessagesプロパティを含むオブジェクトを返すようにします。これにより、メッセージがCanExecute()のその呼び出しにのみ適用されることが明らかになります。ただし、実装する場所/方法(データバインディングなど)によっては、これにより、探している以上に他のシナリオが複雑になる可能性があります。

public class CanExecuteResult
{
    public bool CanExecute { get; set; }
    public IEnumerable<string> Messages { get; set; }
}

public interface ICommand
{
    CanExecuteResult CanExecute();
    void Execute();
}

public class SomeCommand : ICommand
{
    public CanExecuteResult CanExecute()
    {
        var result = new CanExecuteResult { CanExecute = true };
        var messages = new List<string>();

        if (SomeCondition)
        {
            result.CanExecute = false;
            messages.Add("Some reason");
        }

        if (AnotherCondition)
        {
            result.CanExecute = false;
            messages.Add("Another reason");
        }

        result.Messages = messages;

        return result;
    }

    public void Execute() { }
}

明らかに、インターフェースや列挙可能なタイプなどをどのように処理するかについての詳細はあなた次第です。コードはアイデアの単なる表現です。

于 2013-02-06T17:32:37.387 に答える
1

クラスのユーザーにfalse を返した理由 を伝える「理由」のコレクションを使用できます。CanExecute理由は簡単IEnumerable<string>です。

public bool CanExecute() {
  var messages = new List<string>();

  if (!Condition1) {
    messages.Add("Missing Condition1");
  }

  ...

  Messages = messages;
  return messages.Count == 0;
}

public IEnumerable<string> Messages { get; private set; }

その後、クライアント コードはメッセージのコレクションをエンド ユーザーに表示できます。

更新

新しいコマンドをメッセージに関連付けて、見つかった問題を修正する方法をユーザーに提供することもできます。この場合、 の代わりに、IEnumerable<string>その情報をカプセル化する独自のクラスを作成できます。

public class Message {
  public string Text { get; set; }
  public ICommand Command { get; set; }
}

...

public bool CanExecute() {
  var messages = new List<Message>();

  if (!Condition1) {
    messages.Add(
      new Message { 
        Text = "Missing Condition1", 
        Command = new FixCondition1Command() 
      }
    );
  }

  ...

  Messages = messages;
  return messages.Count == 0;
}

public IEnumerable<Message> Messages { get; private set; }
于 2013-02-06T17:37:46.413 に答える
0
    Bool CanExecute()
    {
     if(!CheckXXX)
      throw new Exception("CheckXXX function throws an exception")

     if(!CheckYYY)
      throw new Exception("CheckYYY function throws an exception")

    if(!CheckZZZ)
     throw new Exception("CheckZZZ function throws an exception")

    return true; //everything is working fine    
}
于 2013-02-06T16:45:25.177 に答える