策略设计模式与简单的接口抽象?
The Strategy design pattern vs simple Interface abstraction?
AFAIK,策略设计模式is pretty simple:
接口:
public interface IStrategy
{
object DoAlgorithm(object data);
}
实施 classes :
lass ConcreteStrategyA : IStrategy
{
public object DoAlgorithm(object data)
{
var list = data as List<string>;
list.Sort();
return list;
}
}
class ConcreteStrategyB : IStrategy
{
public object DoAlgorithm(object data)
{
var list = data as List<string>;
list.Sort();
list.Reverse();
return list;
}
}
在 ctor 中获取 IStrategy 的上下文 class:
class Context
{
private IStrategy _strategy;
public Context(IStrategy strategy)
{
this._strategy = strategy;
}
public void SetStrategy(IStrategy strategy)
{
this._strategy = strategy;
}
public void DoSomeBusinessLogic()
{
////
}
}
当然还有 Main 方法:
var context = new Context();
Console.WriteLine("Client: Strategy is set to normal sorting.");
context.SetStrategy(new ConcreteStrategyA());
context.DoSomeBusinessLogic();
问题:
好的,但是它与 :
相比有何不同
Istrategy context = new ConcreteStrategyA (); //or ConcreteStrategyB
Console.WriteLine("Client: Strategy is set to normal sorting.");
context.DoSomeBusinessLogic();
我错过了什么吗?为什么不只使用接口?
除了策略之外,您可能还需要做其他事情...例如,如果您需要添加日志记录或打印有关列表的统计信息 - 您可能不想将其纳入策略。您可能还想动态添加或让用户选择策略,例如通过加载 'plugins'.
通常,您会针对可能需要更改的更短暂和易变的依赖项使用策略,而接口将用于更大或更静态的功能块。例如运行时与配置灵活性的区别。
要使用您的列表排序器示例,该策略可能采用 IEnumerable 并对其进行排序,但您可能希望在最终使用该策略的上述 ListSorter class 中定义其他功能,例如采用不同的输入集合并将它们呈现给排序策略,或以某种方式对它们进行规范化——通过这种方式,您可以解耦代码,因为请求对列表进行排序的组件不关心组件最终如何对其进行排序,排序代码也不关心”不需要了解规范化等。当然,这在较大的应用程序中以及与其他技术结合时更有用,因此很难在像这样的简单示例中进行演示,但希望能给您一个想法。
AFAIK,策略设计模式is pretty simple:
接口:
public interface IStrategy
{
object DoAlgorithm(object data);
}
实施 classes :
lass ConcreteStrategyA : IStrategy
{
public object DoAlgorithm(object data)
{
var list = data as List<string>;
list.Sort();
return list;
}
}
class ConcreteStrategyB : IStrategy
{
public object DoAlgorithm(object data)
{
var list = data as List<string>;
list.Sort();
list.Reverse();
return list;
}
}
在 ctor 中获取 IStrategy 的上下文 class:
class Context
{
private IStrategy _strategy;
public Context(IStrategy strategy)
{
this._strategy = strategy;
}
public void SetStrategy(IStrategy strategy)
{
this._strategy = strategy;
}
public void DoSomeBusinessLogic()
{
////
}
}
当然还有 Main 方法:
var context = new Context();
Console.WriteLine("Client: Strategy is set to normal sorting.");
context.SetStrategy(new ConcreteStrategyA());
context.DoSomeBusinessLogic();
问题:
好的,但是它与 :
相比有何不同Istrategy context = new ConcreteStrategyA (); //or ConcreteStrategyB
Console.WriteLine("Client: Strategy is set to normal sorting.");
context.DoSomeBusinessLogic();
我错过了什么吗?为什么不只使用接口?
除了策略之外,您可能还需要做其他事情...例如,如果您需要添加日志记录或打印有关列表的统计信息 - 您可能不想将其纳入策略。您可能还想动态添加或让用户选择策略,例如通过加载 'plugins'.
通常,您会针对可能需要更改的更短暂和易变的依赖项使用策略,而接口将用于更大或更静态的功能块。例如运行时与配置灵活性的区别。
要使用您的列表排序器示例,该策略可能采用 IEnumerable 并对其进行排序,但您可能希望在最终使用该策略的上述 ListSorter class 中定义其他功能,例如采用不同的输入集合并将它们呈现给排序策略,或以某种方式对它们进行规范化——通过这种方式,您可以解耦代码,因为请求对列表进行排序的组件不关心组件最终如何对其进行排序,排序代码也不关心”不需要了解规范化等。当然,这在较大的应用程序中以及与其他技术结合时更有用,因此很难在像这样的简单示例中进行演示,但希望能给您一个想法。