说装饰器比适配器更透明是什么意思?

时间:2013-03-11 19:30:56

标签: design-patterns

我已经读过装饰器对客户端比适配器更透明,正是这个透明度使嵌套装饰成为可能。在这种情况下,透明度的实际含义是什么?

P.S:我知道这两种设计模式。所以你可以根据这个前提做出答案。

3 个答案:

答案 0 :(得分:5)

装饰器获取给定类型A的对象,并将其包装到相同类型A的对象中。客户端可以使用装饰对象,就像它使用实际对象一样,因为它们具有相同的类型。

适配器获取给定类型A的对象,并将其包装到另一个类型B的对象中。然后,使用原始类型A的客户端必须适应使用另一种类型B.

也就是说,如果我们使用适配器模式,那正是因为客户端需要类型B的对象,并且我们只有一个类型为A的对象。所以我们将它包装到适配器中以使其成为类型的对象乙

这两种模式使用相同的原理(包装),但出于不同的目的。一个装饰器来改变原始对象的行为。用于更改其类型的适配器。

答案 1 :(得分:3)

客户端使用装饰器和装饰对象(两者都有相同的接口)没有区别。因此装饰器是透明的(即客户端不可见)。装饰器也可以由其他装饰器装饰 - 这不会影响客户端。客户端仍然可以认为他正在使用装饰对象。

好的样本是Streams。您可以传递使用任意数量的装饰器(压缩,加密,缓冲)装饰的流,但是对于任何使用流的客户端,这些装饰器将保持不可见。

实际上我不明白为什么适配器可以被认为是透明的。客户端不应该知道适配器的类型,并且客户端不能将适配器视为适配器,因为它们具有不同的接口。

答案 2 :(得分:0)

回答装饰者透明的方式比为什么适配器偷偷摸摸或不稳定更为直接。装饰器倾向于更频繁地嵌套到大规模功能(这通常是正交的,例如BufferedFileWriter增加了缓冲,这并没有真正改变它包装的类的基本操作:它将这些操作委托给原始的)。通常情况下,您可以很容易地看到装饰器正在做什么,因为它隐藏在原始界面中。

适配器可以同样透明。我猜想嵌套适配器更难的原因是你在谈论转换一些状态对象。然后你很快就会发现所有暗示的丑陋(MVC随着它的增长而发生的事情之一)。例如,我有一个旧的应用程序,给我一个输入的风险评级。有一个新的Web界面想要使用它,但它需要另一种格式的数据。我们无法更改原始代码,因此我们引入了翻译的适配器。这是什么翻译?一般是一些国家代表。因此,如果界面不同,它将采取输入并转换并重新调整它们,如果输出需要进一步按摩,同上。如果您对多个适配器进行分层,您很快就会发现自己难以确定谁对所呈现的最终对象(无论是服务还是回馈给消费者)做出了贡献。

装饰器通常不用于这样的翻译工作,而是用于补充我们要么没有代码的东西的功能,或者再次说明新功能正交的地方,因此,我们允许用户或不使用一个或多个装饰者。