2012-08-17 26 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