我正在讨论一些设计模式问题,我查看了GoF中Decorator模式的定义和示例.它说
动态地将附加职责附加到对象.装饰器为子类化提供了灵活的替代扩展功能.
它给出了使用继承的装饰器的例子,但绝对不是动态的.
NetObjectives犯同样的错误:
http://www.netobjectives.com/PatternRepository/index.php?title=TheDecoratorPattern
关于装饰器的Portland Pattern Repository讨论表明,对于什么是装饰器而不是装饰器存在混淆
http://c2.com/cgi/wiki?DecoratorPattern
维基百科通过注意装饰器内的委托应该在构造时设置(其他DI技术也可以)来解释这个矛盾
http://en.wikipedia.org/wiki/Decorator_pattern
Decorator模式的所有示例(在Java或C++中)都需要通过继承或通过实现接口来构造静态构造.然而,GoF中的解释说,附加职责是动态附加的.但这完全是错的.
PPR上的评论讨论了可以在运行时添加方法的动态语言,但Java和C++不是动态的,而Decorator的解释并不是说它仅限于Groovy和Lisp等动态语言.
Decorator的正确解释是不是说在不支持动态方法创建的语言中,涉及静态和动态构造?
GoF的解释完全错误,如他们自己的例子所示,或者我误解了什么?
动态 我认为"动态"这个词的含义与GOF写这本书的时候有所不同.我猜他们打算说的是"在没有实际修改底层对象的代码/定义的情况下向对象添加前/后行为." 对于客户,对象(装饰与否)看起来是相同的.今天,dynamic与动态语言相关联,从这个意义上说,意味着松散的类型以及在运行时向对象添加方法/行为的能力.
子类化的替代方案
装饰器模式是子类化的替代方案.子类在编译时添加行为,并且更改会影响原始类的所有实例; 装饰可以在运行时为单个对象提供新的行为.
当有几种独立的扩展功能方式时,这种差异变得最为重要.在一些面向对象的编程语言中,不能在运行时创建类,并且通常不可能在设计时预测需要哪些扩展组合.这意味着必须为每种可能的组合制作新的课程.相比之下,装饰器是在运行时创建的对象,可以在每次使用的基础上进行组合. - 维基百科
装饰器使用继承,但是它们不从它们正在装饰的对象继承.它们继承了公共接口,以便公开与装饰对象相同的方法(模仿).他们使用组合行为 - 通过委托添加事后行为.
var dao = new PerformanceTrackingDecorator(new TurboSpeedDecorator(SqlDataAccessObject))
// use dao and later..
dao = new PerformanceTrackingDecorator(new TurboSpeedDecorator(XmlDataAccessObject))
//at runtime, I've added certain behavior to Sql and Xml DAOs
Run Code Online (Sandbox Code Playgroud)