如何解耦模式切换和命令 [英] How to decouple mode switching and commands

查看:30
本文介绍了如何解耦模式切换和命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How to decouple a Mode (normally expressed by enums) from its implementation in commands and their relationship? Is their a good pattern describing the loose binding between a mode switch (int, enum, string, ...) and its command calls? I want to add modes via config, so this must be (dynamically) easy extendable (without programming). I already know the command pattern (ICommand in C#/.Net). It could be an Dictionary of Commands and their related mode number, but what about the switching logic?

推荐答案

可以从策略中解耦上下文(切换设计、参数)解决请求(输入)及其响应(输出).

It is possible to decouple context (switching descission, parameters) from the strategy to solve the request (input) and its response (output).

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

You could use e.g. generics to solve this problem for different cases with one code base. For example the strategy is defined by its kind of input and output and a condition to evaluate:

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);
    }
}

上下文有不同的策略,并询问策略的职责(给定条件可以,可以计算一个请求的结果)

The context has different strategies and asks the strategies for their responsibility (given conditions are ok, can calculate the result for an request).

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;
    }
}

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

Let's take a simple example where an input string needs to be resolved to an output string (like a switch case).

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

1. Define your actions (for simplification this is an (as you can see, every Method has its own logic and concern):

    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):

2. Define a condition to run the evaluation (lika a CanExecute of an ICommand):

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

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

... you could even define more conditions (e.g. one condition eval function per strategy) but we use only one here.

3.创建上下文所需的策略对象(这些对象代表切换的不同路径,并为我们提供结果):

3. Create strategy objects required by the context (these symbolize the different paths of the switch and they give us the result):

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

2.初始化你的上下文(代表带有输入的开关体):

2. Initialize your context (represents the switch body with the input):

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

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

3. Wire them into the code (e.g. execute "switch" by a button click):

    private void ButtonClick(object sender, RoutedEventArgs e)
    {
        var message = context.Evaluate(textBox1.Text);

        if (message != null) MessageBox.Show(message); // display result
    }

...就是这样.

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

The context gives you the right strategy (can do the right actions or give the "tools" you need to do some actions (e.g. an ICommand).

这篇关于如何解耦模式切换和命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆