装饰设计模式vs.继承? [英] Decorator design pattern vs. inheritance?

查看:136
本文介绍了装饰设计模式vs.继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从wiki http://en.wikipedia.org/wiki/Decorator_pattern 中阅读了装饰设计模式,以及来自 http://www.vincehuston.org/dp/decorator.html 的代码示例。



我看到传统继承遵循is-a模式,而装饰器遵循has-a模式。装饰器的调用约定看起来像'皮肤'在'核心'。例如

  I * anXYZ = new Z(new Y(new X(new A))); 

p>但是仍然有一些问题我不明白:


  1. wiki是什么意思'可以用于在运行时 扩展(装饰)某个对象的功能? 'new ...(new ...(new ...))'是一个运行时调用,很好,但是'AwithXYZ anXYZ;'是编译时的继承,是坏的?


  2. 从代码示例链接,我可以看到类定义数在两个实现中几乎相同。我记得在一些其他设计模式的书,如头第一设计模式。他们使用starbuzz咖啡作为例子,说传统的继承会导致'类爆炸因为每一种咖啡的组合,你会想出一个类。但是在这种情况下装饰器不一样吗?如果一个装饰器类可以接受任何抽象类并装饰它,那么我想它可以防止爆炸,但从代码示例,你有精确的类定义,不少...


有人可以帮忙解释吗?



非常感谢。

解决方案

让我们以一些抽象流为例,想象你想通过他们提供加密和压缩服务。



有装饰器你有(伪代码):

  Stream plain = Stream 
Stream encrypted = EncryptedStream(Stream());
Stream zipped = ZippedStream(Stream());
Stream zippedEncrypted = ZippedStream(EncryptedStream(Stream());
Stream encryptedZipped = EncryptedStream(ZippedStream(Stream());

继承,你有:

  
class EncryptedStream():Stream {...}
class ZippedStream():Stream {...}
class ZippedEncryptedStream():EncryptedStream {...} EncryptedZippedStream():ZippedStream {...}

1)with decorator,you combine the functionality at runtime ,每个类只负责一个方面的功能(压缩,加密,...)



2)在这个简单的例子中,我们有3类与装饰器,和5与继承。现在让我们添加一些服务,例如过滤和限幅。使用装饰器,您只需要2个以上的类来支持所有可能的场景,例如过滤 - >剪切 - >压缩 - >编码。
使用继承,你需要为每个组合提供一个类,所以你最终需要几十个类。


I've read the decorator design pattern from wiki http://en.wikipedia.org/wiki/Decorator_pattern, and code example from http://www.vincehuston.org/dp/decorator.html.

I see the point that traditional inheritance follows an 'is-a' pattern whereas decorator follows a 'has-a' pattern. And the calling convention of decorator looks like a 'skin' over 'skin' .. over 'core'. e.g.

I* anXYZ = new Z( new Y( new X( new A ) ) );

as demonstrated in above code example link.

However there are still a couple of questions that i do not understand:

  1. what does wiki mean by 'The decorator pattern can be used to extend (decorate) the functionality of a certain object at run-time'? the 'new ...(new... (new...))' is a run-time call and is good but a 'AwithXYZ anXYZ;' is a inheritance at compile time and is bad?

  2. from the code example link i can see that the number of class definition is almost the same in both implementations. I recall in some other design pattern books like 'Head first design patterns'. They use starbuzz coffee as example and say traditional inheritance will cause a 'class explosion' 'cause for each combination of coffee, you would come up with a class for it. But isn't it the same for decorator in this case? If a decorator class can take ANY abstract class and decorate it, then i guess it does prevent explosion, but from the code example, you have exact # of class definitions, no less...

Could anyone help to explain?

Thanks a lot,

解决方案

Let's take some abstract streams for example and imagine you want to provide encryption and compression services over them.

With decorator you have (pseudo code):

Stream plain = Stream();
Stream encrypted = EncryptedStream(Stream());
Stream zipped = ZippedStream(Stream());
Stream zippedEncrypted = ZippedStream(EncryptedStream(Stream());
Stream encryptedZipped = EncryptedStream(ZippedStream(Stream());

With inheritance, you have:

class Stream() {...}
class EncryptedStream() : Stream {...}
class ZippedStream() : Stream {...}
class ZippedEncryptedStream() : EncryptedStream {...}
class EncryptedZippedStream() : ZippedStream {...}

1) with decorator, you combine the functionality at runtime, depending on your needs. Each class only takes care of one facet of functionality (compression, encryption, ...)

2) in this simple example, we have 3 classes with decorators, and 5 with inheritance. Now let's add some more services, e.g. filtering and clipping. With decorator you need just 2 more classes to support all possible scenarios, e.g. filtering -> clipping -> compression -> encription. With inheritance, you need to provide a class for each combination so you end up with tens of classes.

这篇关于装饰设计模式vs.继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆