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