【问题标题】:When and How Strategy pattern can be applied instead of decorator pattern?何时以及如何应用策略模式而不是装饰器模式?
【发布时间】:2011-05-20 06:28:44
【问题描述】:

我正在学习设计模式并尝试遵循 Go4 书籍。在第 179 页,在装饰器模式章节中,有一行写着

"..通过将策略的数量从一个扩展到一个 开放式列表,我们达到和嵌套装饰器一样的效果 递归。”

我不太明白这个说法。

策略侧重于拥有独立的算法,这些算法可以动态设置,并且不太了解它们所在的客户端。

而装饰者并不完全独立于他们所装饰的客户。实际上,它们与它们所装饰的对象具有相同的超类型。

我在这里漏掉了一点吗?

【问题讨论】:

    标签: design-patterns strategy-pattern


    【解决方案1】:

    我将引用更多我认为有意义的上下文。

    在组件类本质上是重量级的情况下,策略是更好的选择,从而使装饰器模式成本过高而无法应用。在策略模式中,组件将其一些行为转发给单独的策略对象。策略模式允许我们通过替换策略对象来改变或扩展组件的功能。

    例如,我们可以通过让组件将边框绘制推迟到单独的 Border 对象来支持不同的边框样式。 Border 对象是一个封装了边框绘制策略的 Strategy 对象。通过将策略的数量从一个扩展到一个开放式列表,我们实现了与递归嵌套装饰器相同的效果。

    这就是说,这两种模式都可以用来向你的基础组件添加行为,而对于装饰器,要添加多个行为,你可以嵌套装饰器,而对于策略,你需要使用多种策略。

    你说得对,策略通常比装饰器更独立于主组件,但他们有可能知道组件。为了使用策略模式,主要组件知道策略的存在,而装饰器不需要。

    【讨论】:

      【解决方案2】:

      要使用他们的示例,您可能有一个可以滚动的窗口类和/或以各种方式绘制其边框(或根本不绘制)。如果您要使用继承来涵盖所有这些功能,那么您需要一个子类来处理每种可行的功能组合(无边框无滚动、无边框无滚动、无边框滚动、边框和滚动等)​​。当您添加更多功能时,这是一个不灵活的维护噩梦,因为类的数量呈爆炸式增长。

      他们在这里提出的主要观点是,您可以使用策略模式或装饰器模式来更好地解决这个问题。您可以有一个封装滚动策略对象和边框策略对象的 Window 类。或者,您可以使用 Window 对象,将其包装在边框装饰器中,然后将其包装在滚动装饰器中。

      但是您的理解完全正确;这是两种不同的设计模式,具有不同的特点,导致不同的应用。使用装饰器,组件不知道正在添加功能的代理......因此您最终倾向于围绕现有的组件类进行构建。对于 Strategy,情况正好相反,因为组件使用(因此知道)代理来执行各种任务 - 这些代理通常不知道它们的管理组件。

      【讨论】:

        【解决方案3】:

        当您想对某事使用多种方法时,请使用策略模式。当您想创建某些东西可能会或可能不会用于更改对象/组件/任何东西的东西时,那么您应该使用装饰器。换句话说,也可以说装饰器可能会为对象添加功能(装饰),而策略可能会交换功能。

        【讨论】:

          【解决方案4】:

          区别在于,在策略模式中,一个策略对象可以一次用于向上下文提供信息。使用 Decorator,您可以将策略堆叠在一起,从而获得他们所说的“开放式”数字。

          【讨论】:

            【解决方案5】:

            当对象的身份对您很重要时,可以应用策略模式。无论应用了多少策略,对象标识仍然存在,但对于装饰器模式 对象相互封装,原始身份将在转换中丢失

            • 装饰器模式改变对象的皮肤

            • 策略模式改变了对象的内涵。

            【讨论】:

              猜你喜欢
              • 2014-12-12
              • 2012-02-17
              • 1970-01-01
              • 2017-09-19
              • 1970-01-01
              • 2010-12-05
              • 1970-01-01
              • 1970-01-01
              • 2020-02-29
              相关资源
              最近更新 更多