GoF explanation for Decorator pattern is confusing (or just plain wrong)

I turn to some design pattern questions, and I looked at the definition and examples of the Decorator pattern in GoF. It says:

Attach additional responsibilities to the object dynamically. Decorators provide a flexible alternative to a subclass to extend functionality.

Here are examples of decorators that use inheritance that is definitely not dynamic.

NetObjectives makes the same error:

http://www.netobjectives.com/PatternRepository/index.php?title=TheDecoratorPattern

A discussion of the vault in the Portland Restorer Decorator indicates that there is confusion about what is and is not a decorator.

http://c2.com/cgi/wiki?DecoratorPattern

Wikipedia has some idea of ​​this contradiction, noting that the delegate inside the Decorator needs to be set at build time (other DI methods will also work)

http://en.wikipedia.org/wiki/Decorator_pattern

All examples of the Decorator template (in Java or C ++) require a static construct, either through inheritance or by implementing an interface. An explanation in GoF says that additional responsibilities are applied dynamically. But this is simply wrong.

The comments in PPR speak of dynamic languages ​​that can add methods at runtime, but Java and C ++ are not dynamic, and Decorator's explanation does not say that it is limited to dynamic languages ​​such as Groovy and Lisp.

Was there a correct explanation for Decorator to say that in languages ​​that do not support dynamic method creation, both static and diamantic constructions are involved?

Is the GoF explanation simply wrong, as shown in their own examples, or didn’t I understand something?

+4
source share
2 answers

It seems that the GoF explanation is simply poorly written. Calling Decorator is an alternative to a subclass when their examples are subclasses is very confusing.

GoF says that a decorated item and its Decorators should have appropriate interfaces. This is apparently a template requirement, and they demonstrate this with inheritance. Thus, there is a dynamic and static component for their Decorator template.

I could also see how you can invert the template and make Decorator a delegate to the decorated object, but this will probably lead to a confusing implementation.

In a dynamic language like Lisp or Groovy, I think you could just combine the design logic into the draw () logic of the class itself. An interface conformance requirement would not be necessary, and there would be no need for separate classes for the decorated object and Decorator.

I'm going to add Lisp training to my slave list so that I can see how design patterns change in a dynamic language.

0
source

Dynamic I think the word “dynamic” meant something different than when GOF wrote a book. I suppose they were going to say: "adding behavior before / after publishing the object without actually changing the code / defining the underlying object." For customers, the object (whether or not designed) looks the same. Today, dynamics is associated with dynamic languages ​​and in this sense means free typing and the ability to add methods / behavior to an object at runtime.

Subclass Alternative

Decorator drawing is an alternative to a subclass. The subclass adds compilation time behavior, and the change affects all instances of the original class; decoration can provide new runtime behavior for individual objects.

This distinction becomes most important when there are several independent ways to extend functionality. In some object-oriented programming languages, classes cannot be created at runtime, and it is usually not possible to predict, at design time, which combination of extensions will be needed. This would mean that a new class should be made for every possible combination. In contrast, decorators are objects created on and can be combined for use. - wikipedia

Decorators use inheritance, but they do not inherit from the object that they decorate. They inherit a common interface to expose the same methods as a decorated object (impersonation). They use composition for behavior - add behavior before posting after delegation.

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 
+6
source

All Articles