如何将模式(通常由枚举表示)与其在命令中的实现及其关系中解耦?它们是描述模式开关(int,enum,string,...)与其命令调用之间松散绑定的好模式吗?我想通过配置添加模式,所以这必须(动态)易于扩展(无需编程)。我已经知道命令模式(C#/.Net 中的 ICommand)。它可能是命令字典及其相关的模式编号,但切换逻辑呢?
问问题
279 次
1 回答
2
可以将上下文(切换决策、参数)与解决请求(输入)及其响应(输出)的策略解耦。
您可以使用例如泛型来通过一个代码库针对不同情况解决此问题。例如,策略由其输入和输出类型以及评估条件定义:
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;
}
}
让我们举一个简单的例子,输入字符串需要解析为输出字符串(如 switch case)。
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)。
于 2011-07-27T08:11:22.693 回答