截至目前,我的代码有多个if else语句分支,具体取决于字符串的值。即。
if(input == "condition1")
{
// Some logic
}
else if(input =="condition1")
{
// Some other logic
}
我打算使用策略模式。这是正确的方法吗?如果是,我如何根据条件创建正确的具体策略对象?
由于
答案 0 :(得分:3)
在您提供的代码示例中,策略不会让您远离已有的if条件。您最终需要工厂来创建策略对象,如下所示:
static class StrategyFactory
{
static IStrategy CreateStrategy(string input)
{
if (input == "condition1")
{
return new StrategyForCondition1();
}
else if (input == "condition2")
{
return new StrategyForCondition2();
}
}
}
这就是为什么我不会为你的案例推荐策略。
一个非常优雅的替代解决方案是使用Dictionary,其中键是输入字符串值,Action是if语句的内容:
var actions = new Dictionary<string, Action>
{
{"condition1", () => Console.WriteLine("condition1")},
{"condition2", NameOfMethodThatHandlesCondition2}
};
现在,这个解决方案的优点在于您只使用一行代码:
actions[input];
请参阅此处的示例:http://elegantcode.com/2009/01/10/refactoring-a-switch-statement/
您的代码示例中的一个问题是您要与字符串进行比较...这可能是任何可能的值。如果可能,请创建一个代表所有可能条件的枚举。这样可以防止遇到您没预料到的字符串值。
答案 1 :(得分: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()
答案 2 :(得分:-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]();