【问题标题】:The Strategy design pattern vs simple Interface abstraction?策略设计模式与简单的接口抽象?
【发布时间】:2019-05-19 19:13:37
【问题描述】:

AFAIK,策略设计模式is pretty simple

界面:

public interface IStrategy
    {
        object DoAlgorithm(object data);
    }

实现类:

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 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();

我错过了什么吗?为什么不只使用接口?

【问题讨论】:

  • 您能否说明您的第二个建议如何解决“为我的操作选择排序算法”?到目前为止,您需要两个不同的 ConcreteStrategyA 实现来替换排序......或者一般来说像“记录策略的数量”*“排序策略的数量”*......操作的实现......
  • @AlexeiLevenkov class ConcreteStrategyB/A : IStrategy 对于两个类应该保持不变。我可以使用if 来选择我想要new 的形式。在第一个示例中,他们做了context.SetStrategy(new ConcreteStrategyA());,而在我的示例中,我可以只做Istrategy context = new ConcreteStrategyA ();(如果这就是您要问的)。但是,如果这个想法是将功能添加到一个集中的地方,那么我理解。 (@milney 说过的话)

标签: c# design-patterns strategy-pattern


【解决方案1】:

除了策略之外,您可能还需要做其他事情...例如,如果您需要添加日志记录或打印有关列表的统计信息 - 您可能不想将其纳入您的策略。您可能还希望动态添加或让用户选择策略,例如通过加载“插件”。

通常,您会使用策略来处理可能需要更改的更短寿命和易变的依赖关系,而接口将用于更大或更静态的功能。例如运行时与配置灵活性的区别。

要使用您的 List Sorter 示例,该策略可能会采用 IEnumerable 并对其进行排序,但您可能希望在上述 ListSorter 类中定义最终使用该策略的附加功能,例如采用不同的输入集合并呈现它们到排序策略,或者以某种方式规范化它们——这样你就可以解耦你的代码,因为请求列表排序的组件并不关心组件最终如何排序,排序代码不需要知道归一化等。当然,这在更大的应用程序中以及与其他技术结合使用时更有用,因此很难在像这样的简单示例中演示,但希望能给您一个想法。

【讨论】:

  • 不是装饰器吗?哪个增加了功能?
  • 模式是工具。您可以使用在您的应用程序中最有意义的那些。您可以使用装饰器添加横切关注点,是的。就像您可以使用策略模式来允许交换实现一样。没有人说策略模式是必要的或做任何事情的最佳方式,它只是另一种工具。
猜你喜欢
  • 2015-05-19
  • 2014-09-25
  • 2018-09-20
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 2017-10-10
  • 1970-01-01
相关资源
最近更新 更多