2010-12-04 133 views
7

我正在学习设计模式并试图遵循Go4书。在页面:179,在装饰图案章,还有它说何时以及如何应用策略模式而不是装饰模式?

” ..by的只从一个战略的数量延伸到 开放式列表中的行,我们实现为嵌套同样的效果装饰者 递归。“

我并没有完全得到这种说法。

战略侧重于具有独立的算法,它可以动态地设置,不知道太多关于他们在设置客户端。

而装饰都不太独立,他们装饰的客户。事实上,它们与它们装饰的对象具有相同的超类型。

我在这里错过了一个观点吗?

回答

14

我会引用一点我认为需要的上下文,以使其有意义。

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

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

这一切的意思是,这两种模式可以用来添加行为到您的基本组成部分,并与装饰,添加多种行为,你可以窝在装饰,同时与策略,你需要使用多个策略。

你说得对,策略通常比装饰者更独立于主要组件,但它们有可能知道组件。而要使用策略模式,主要组件意识到策略的存在,而Decorator则不需要这些策略。

6

要使用自己的例子,你可能有可滚动的窗口类和/或有其边界以各种方式(或根本不)画。如果您要使用继承来覆盖所有这些功能,则对于每个可行的功能组合(无边框无滚动,无滚动边框,无边框滚动,边框和滚动等)​​,您都需要一个子类。这是一个不灵活的维护噩梦,因为您添加更多的功能,因为类的数量爆炸。

他们正在做这方面的主要问题是,你可以使用的策略模式或装饰模式,以更好地解决这个问题。你可以有一个Window类,它封装了一个滚动策略对象和一个边界策略对象。或者你可以把你的Window对象包装在一个边界装饰器中,并将其包装在一个滚动装饰器中。

但你完全正确的理解;这些是具有不同特征的两种不同设计模式,这导致不同的应用。使用装饰器,组件不知道正在添加功能的代理......所以你往往最终围绕现有的组件类构建。随着战略,这是另一种方式,因为组件正在使用(并因此知道)代理执行各种任务 - 这些代理通常不知道他们的治理组件。

+0

该示例使事情变得清晰。 – Sandbox 2010-12-04 18:49:44

0

区别在于,在战略模式中,可以使用一个策略对象一次向上下文提供信息。使用装饰者,你可以将战略叠加在一起,从而得到他们称之为“开放式”的数字。

0

当对象的标识对您很重要时,可以应用策略模式。对象的身份仍然是多少策略应用于不论但Decorator模式 对象封装内相互原来的身份将在转换中丢失

  • Decorator模式改变对象的皮肤

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

1

当您想要使用多种方法来使用某种策略模式时。当你想创建某些东西可能会或可能不会被用来改变对象/组件/任何东西时,那么你应该使用装饰器。换句话说,也可以说装饰器可能会添加功能(装饰)对象,并且策略可能会交换功能。