截至目前我的代码有多个if else语句分支,具体取决于字符串的值。即策略设计模式适用于基于字符串比较的逻辑吗?
if(input == "condition1")
{
// Some logic
}
else if(input =="condition1")
{
// Some other logic
}
我打算使用策略模式。这是正确的方法吗?如果是,我如何根据条件创建正确的具体策略对象?
谢谢
截至目前我的代码有多个if else语句分支,具体取决于字符串的值。即策略设计模式适用于基于字符串比较的逻辑吗?
if(input == "condition1")
{
// Some logic
}
else if(input =="condition1")
{
// Some other logic
}
我打算使用策略模式。这是正确的方法吗?如果是,我如何根据条件创建正确的具体策略对象?
谢谢
为什么不只是使用开关?
switch (input) {
case "condition1":
// do stuff
break;
case "condition2":
// do stuff....
break;
default:
// default stuff
break;
}
或无法使用一个Dictionary<string,Action>
var actions=new Dictionary<string,Action> { { "condition1",() => {code}}, {"condition2",) => {code}};
然后..
if (actions.ContainsKey(input)) actions[input]();
如果您真的添加了评论,而不是仅仅标记答案,那将会很不错。 – 2012-08-17 15:24:37
这里是一个伟大的网站使用不同模式的类型在C#中一些很好的例子。
Strategy Design Patterns in C# and VB
// Strategy pattern -- Structural example
using System;
namespace DoFactory.GangOfFour.Strategy.Structural
{
/// <summary>
/// MainApp startup class for Structural
/// Strategy Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
Context context;
// Three contexts following different strategies
context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Strategy' abstract class
/// </summary>
abstract class Strategy
{
public abstract void AlgorithmInterface();
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("Called ConcreteStrategyA.AlgorithmInterface()");
}
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class ConcreteStrategyB : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("Called ConcreteStrategyB.AlgorithmInterface()");
}
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class ConcreteStrategyC : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("Called ConcreteStrategyC.AlgorithmInterface()");
}
}
/// <summary>
/// The 'Context' class
/// </summary>
class Context
{
private Strategy _strategy;
// Constructor
public Context(Strategy strategy)
{
this._strategy = strategy;
}
public void ContextInterface()
{
_strategy.AlgorithmInterface();
}
}
}
Output
Called ConcreteStrategyA.AlgorithmInterface()
Called ConcreteStrategyB.AlgorithmInterface()
Called ConcreteStrategyC.AlgorithmInterface()
在您所提供的代码示例,战略是不会让你从你已经拥有的,如果条件了。你会最终需要一个工厂来创建你的战略目标如下:
static class StrategyFactory
{
static IStrategy CreateStrategy(string input)
{
if (input == "condition1")
{
return new StrategyForCondition1();
}
else if (input == "condition2")
{
return new StrategyForCondition2();
}
}
}
这就是为什么我不建议战略的情况。
一个非常优雅的另一种方法是使用一个字典,其中的关键是输入字符串值,并且动作是if语句的内容:
var actions = new Dictionary<string, Action>
{
{"condition1",() => Console.WriteLine("condition1")},
{"condition2", NameOfMethodThatHandlesCondition2}
};
现在,这种解决方案的优点在于你这里
actions[input];
见的例子:只有1行代码中使用它http://elegantcode.com/2009/01/10/refactoring-a-switch-statement/您的代码示例中
的一个问题是,你是COMPAR一个字符串...可能是任何可能的值。如果可能的话,创建一个代表所有可能条件的枚举。这将防止出现您不期待的字符串值。
使用工厂+1。这样,确定使用哪种策略的责任在于一个单独的课程中。此外,使用枚举而不是字符串的好建议。 – 2012-11-25 07:17:07
你可以阅读这篇文章http://www.dofactory.com/Patterns/PatternStrategy.aspx或这篇文章http://www.codeproject.com/Articles/346873/Understanding-and-Implementing-the-Strategy- Patter – 2012-08-17 15:20:04