2012-08-17 78 views
2

截至目前我的代码有多个if else语句分支,具体取决于字符串的值。即策略设计模式适用于基于字符串比较的逻辑吗?

if(input == "condition1") 
{ 
    // Some logic 
} 
else if(input =="condition1") 
{ 
    // Some other logic 
} 

我打算使用策略模式。这是正确的方法吗?如果是,我如何根据条件创建正确的具体策略对象?

谢谢

+0

你可以阅读这篇文章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

回答

-2

为什么不只是使用开关?

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](); 
+0

如果您真的添加了评论,而不是仅仅标记答案,那将会很不错。 – 2012-08-17 15:24:37

0

这里是一个伟大的网站使用不同模式的类型在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() 
3

在您所提供的代码示例,战略是不会让你从你已经拥有的,如果条件了。你会最终需要一个工厂来创建你的战略目标如下:

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一个字符串...可能是任何可能的值。如果可能的话,创建一个代表所有可能条件的枚举。这将防止出现您不期待的字符串值。

+2

使用工厂+1。这样,确定使用哪种策略的责任在于一个单独的课程中。此外,使用枚举而不是字符串的好建议。 – 2012-11-25 07:17:07