【问题标题】:How to decouple mode switching and commands如何解耦模式切换和命令
【发布时间】:2011-07-25 17:03:31
【问题描述】:

如何将模式(通常由枚举表示)与其在命令中的实现及其关系中解耦? 它们是描述模式开关(int,enum,string,...)与其命令调用之间松散绑定的好模式吗?我想通过配置添加模式,所以这必须(动态)易于扩展(无需编程)。我已经知道命令模式(C#/.Net 中的 ICommand)。它可能是一个命令字典及其相关的模式编号,但是切换逻辑呢?

【问题讨论】:

    标签: c# design-patterns architecture command decoupling


    【解决方案1】:

    可以将上下文(切换决策、参数)与策略解耦 解决请求(输入)及其响应(输出)。

    你可以使用例如使用一个代码库针对不同情况解决此问题的泛型。 例如,策略由其输入和输出类型以及评估条件定义:

    public class Strategy<TInput, TOutput>
    {
        public Predicate<TInput> Condition { get; private set; }
        public Func<TInput, TOutput> Result { get; private set; }
    
        public Strategy(Predicate<TInput> condition, Func<TInput, TOutput> result)
        {
            Condition = condition;
            Result = result;
        }
    
        public TOutput Evaluate(TInput input)
        {
            return Condition(input) ? Result(input) : default(TOutput);
        }
    }
    

    上下文有不同的策略,并要求这些策略负责 (给定条件可以,可以计算一个请求的结果)。

    public class Context<TInput, TOutput>
    {
        private List<Strategy<TInput, TOutput>> Strategies { get; set; }
    
        public Context(params Strategy<TInput, TOutput>[] strategies)
        {
            Strategies = strategies.ToList();
        }
    
        public TOutput Evaluate(TInput input)
        {
            var result = default(TOutput);
            foreach (var strategy in Strategies)
            {
                result = strategy.Evaluate(input);
    
                if (!Equals(result, default(TOutput)))
                    break;
            }
    
            return result;
        }
    }
    

    我们举一个简单的例子,输入字符串需要解析为输出字符串 (就像一个开关盒)。

    1.定义您的操作(为简化起见,这是一个(如您所见,每个方法都有自己的逻辑和关注点):

        private static string Move(string s)
        {
            if (s == "move")
                return "doMove"; // here could be some more action...
            return null;
        }
    
        private static string Query(string s)
        {
            if (s == "point")
                return "queryPoint"; // here could be some more action...
            return null;
        }
    

    2。定义一个条件来运行评估(比如 ICommand 的 CanExecute):

        private static bool Condition(string s)
        {
            return !string.IsNullOrEmpty(s); // could eval different states, values
        }
    

    ...您甚至可以定义更多条件(例如,每个策略一个条件评估函数) 但我们这里只使用一个。

    3.创建上下文所需的策略对象(它们象征着切换的不同路径,它们给了我们结果):

     var navigate = new Strategy<string, string>(Condition, Move);
     var query = new Strategy<string, string>(Condition, Query);
    

    2。初始化您的上下文(表示带有输入的开关主体):

     var strategies = new List<Strategy<string, string>> {navigate, query};
     var context = new Context<string, string>(strategies.ToArray());
    

    3.将它们连接到代码中(例如,通过单击按钮执行“切换”):

        private void ButtonClick(object sender, RoutedEventArgs e)
        {
            var message = context.Evaluate(textBox1.Text);
    
            if (message != null) MessageBox.Show(message); // display result
        }
    

    ...就是这样。

    上下文为您提供正确的策略(可以执行正确的操作或提供执行某些操作所需的“工具”(例如 ICommand)。

    【讨论】:

      猜你喜欢
      • 2016-05-18
      • 2012-10-22
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 2022-12-16
      相关资源
      最近更新 更多