use*_*625 24 c++ design-patterns
我认为传统继承遵循'is-a'模式,而decorator遵循'has-a'模式.装饰者的调用约定看起来像'皮肤'上的'皮肤'......超过'核心'.例如
I* anXYZ = new Z( new Y( new X( new A ) ) );
Run Code Online (Sandbox Code Playgroud)
如上面的代码示例链接所示.
但是仍然有一些我不明白的问题:
wiki是什么意思'装饰模式可以用来在运行时扩展(装饰)某个对象的功能'?'new ...(new ...(new ...))'是一个运行时调用,但很好但是'AwithXYZ anXYZ;' 是编译时的继承而且不好?
从代码示例链接中我可以看到,两个实现中类定义的数量几乎相同.我记得在其他一些设计模式书中,比如"Head first design patterns".他们使用starbuzz咖啡作为例子,并说传统的继承将导致"阶级爆炸",因为对于每种咖啡组合,你会想出一个类.
但在这种情况下装饰者是不是一样的?如果一个装饰器类可以接受任何抽象类并进行装饰,那么我猜它确实可以防止爆炸,但是从代码示例中,你可以得到确切的类定义,不能少......
有人会解释吗?
Zde*_*vic 71
我们以一些抽象流为例,想象一下你想为它们提供加密和压缩服务.
使用装饰器(伪代码):
Stream plain = Stream();
Stream encrypted = EncryptedStream(Stream());
Stream zipped = ZippedStream(Stream());
Stream zippedEncrypted = ZippedStream(EncryptedStream(Stream());
Stream encryptedZipped = EncryptedStream(ZippedStream(Stream());
Run Code Online (Sandbox Code Playgroud)
有了继承,你有:
class Stream() {...}
class EncryptedStream() : Stream {...}
class ZippedStream() : Stream {...}
class ZippedEncryptedStream() : EncryptedStream {...}
class EncryptedZippedStream() : ZippedStream {...}
Run Code Online (Sandbox Code Playgroud)
1)使用装饰器,您可以根据需要在运行时组合功能.每个类只关注功能的一个方面(压缩,加密......)
2)在这个简单的例子中,我们有3个带有装饰器的类,5个带有继承的类.现在让我们添加一些服务,例如过滤和剪辑.使用装饰器,您只需要2个类来支持所有可能的场景,例如过滤 - >剪切 - >压缩 - >编码.通过继承,您需要为每个组合提供一个类,以便最终获得数十个类.
按相反顺序:
2)例如,有10个不同的独立扩展,在运行时可能需要任何组合,10个装饰器类将完成这项工作.要通过继承涵盖所有可能性,您需要1024个子类.并且没有办法解决大规模的代码冗余问题.
1)想象一下,你有1024个子类可以在运行时选择.尝试草拟出所需的代码.请记住,您可能无法决定选择或拒绝选项的顺序.还要记住,在扩展它之前,您可能需要使用一段时间.来吧,试试吧.相比之下,使用装饰器进行操作是微不足道的.