2

我有一个遵循命令模式的类。它有 2 个方法,即 Execute 和 CanExecute,用于检查是否调用 Execute(它们派生自ICommand)。CanExecute 调用一些方法来检查所有必需的服务是否正在运行、版本是否正确等。

调用 CanExecute 后,它可能会失败并返回 false,我需要知道原因。是不是因为版本不好、服务、文件丢失等原因?

了解问题所在的最佳策略是什么

一种选择是,每当所需条件失败时,我都可以抛出一个异常,该异常将在消息字段中描述错误。但是,它可能会失败,并且您不应该使用异常来进行常规控制流。所以我真的不确定。

谢谢你。

4

3 回答 3

1

更新:根据反馈重新设计。

由于 UI 需要 CanExecute() 返回 false 的原因,我想到了两件事:

选项 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() 返回一个包含布尔值以及可枚举消息属性的对象。这表明消息仅适用于 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

您可以使用一组“原因”来告诉该类的用户为什么 CanExecute返回 false。原因可以很简单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 回答