我正在学习设计模式,并尝试按照Go4的说法进行操作。在页面:179,在装饰模式章节中,有一行说
" ...通过将策略的数量从一个扩展到一个 开放式列表,我们实现与嵌套装饰器相同的效果 递归"
我没有得到这个声明。
策略侧重于拥有独立的算法,这些算法可以动态设置,并且对它们所设置的客户端不太了解。
而装饰者并不完全独立于他们装饰的客户。事实上,它们与它们装饰的物体具有相同的超类型。
我在这里错过了一点吗?
答案 0 :(得分:14)
我会引用一些我认为需要的背景来理解这一点。
在Component类本质上是重量级的情况下,策略是更好的选择,从而使得Decorator模式的成本太高而无法应用。在策略模式中,组件将其一些行为转发给单独的策略对象。策略模式允许我们通过替换策略对象来改变或扩展组件的功能。
例如,我们可以通过让组件将边框绘制延迟到单独的Border对象来支持不同的边框样式。 Border对象是一个策略对象,它封装了边框绘制策略。通过将策略的数量从一个扩展到一个开放式列表,我们可以递归地获得与嵌套装饰器相同的效果。
所有这一切都说两种模式都可以用来向你的基础组件添加行为,而使用Decorator,添加多种行为,你可以嵌套装饰器,而使用策略,你需要使用多种策略。 / p>
你是对的,策略通常比装饰器更独立于主要组件,但是他们可能知道组件。并且为了使用策略模式,主要组件意识到策略的存在,而Decorator则不需要这些策略。
答案 1 :(得分:6)
要使用他们的示例,您可能有一个窗口类可以滚动和/或以各种方式绘制边框(或根本不绘制)。如果你要使用继承来覆盖所有这些功能,那么每个可行的功能组合都需要一个子类(没有边框没有滚动,没有滚动的边框,没有边框的滚动,边框和滚动等)。这是一个不灵活的维护噩梦,因为您添加了更多功能,因为类的数量激增。
他们在这里提出的要点是你可以使用策略模式或装饰模式来更好地解决这个问题。你可以有一个Window类,它封装了一个滚动策略对象和一个边框策略对象。或者您可以将您的Window对象包装在边框装饰器中并将其包装在滚动装饰器中。
但是你的理解是完全正确的;这是两种不同的设计模式,具有不同的特性,导致不同的应用。使用Decorator,Component不知道正在添加功能的代理程序......因此您最终会围绕现有的组件类构建。使用策略,这是另一种方式,因为组件正在使用(并因此知道)代理来执行各种任务 - 这些代理通常不了解其管理组件。
答案 2 :(得分:1)
当您想要使用多种方法时,请使用策略模式。当你想要创建某些东西,某些东西可能会或可能不会被用来改变一个对象/组件/什么,那么你应该使用装饰器。换句话说,也可以说装饰者可能会添加一个对象的功能(装饰),而策略很可能会交换功能。
答案 3 :(得分:0)
区别在于,在策略模式中,一个策略对象可用于一次向上下文提供信息。使用Decorator,您可以将策略叠加在一起,从而得到它们所称的“开放式”数字。
答案 4 :(得分:0)
当对象的身份对您很重要时,可以应用策略模式。无论应用了多少策略,对于Decorator模式,对象标识仍然存在 对象被封装在彼此内部,原始身份将在转换中丢失
装饰器图案会改变对象的外观
策略模式改变了对象的内容。