C# 如何将模式切换和命令解耦

C# 如何将模式切换和命令解耦,c#,design-patterns,architecture,command,decoupling,C#,Design Patterns,Architecture,Command,Decoupling,如何将模式(通常由枚举表示)与其在命令中的实现及其关系解耦? 它们是描述模式开关(int、enum、string等)及其命令调用之间松散绑定的好模式吗?我想通过配置添加模式,所以这必须(动态)易于扩展(无需编程)。我已经知道命令模式(C#/.Net中的ICommand)。它可以是命令及其相关模式编号的字典,但是切换逻辑呢?可以将上下文(切换拒绝、参数)与策略解耦 解决请求(输入)及其响应(输出) 例如,您可以使用泛型来解决一个代码库中不同情况下的此问题。 例如,战略由其输入和输出类型以及评估条件

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

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

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

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);
    }
}
2。定义一个条件来运行评估(如可以执行ICommand):

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

3。创建上下文所需的策略对象(这些对象表示切换的不同路径,并给出结果):

。。。就这样。

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

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;
    }
}
    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;
    }
    private static bool Condition(string s)
    {
        return !string.IsNullOrEmpty(s); // could eval different states, values
    }
 var navigate = new Strategy<string, string>(Condition, Move);
 var query = new Strategy<string, string>(Condition, Query);
 var strategies = new List<Strategy<string, string>> {navigate, query};
 var context = new Context<string, string>(strategies.ToArray());
    private void ButtonClick(object sender, RoutedEventArgs e)
    {
        var message = context.Evaluate(textBox1.Text);

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