Saturday, November 5, 2016

Composite versus Decorator versus Proxy

From GOF

Composite  and Decorator  have similar structure diagrams, reflecting the fact that both rely
on recursive composition to organize an open-ended number of objects. This commonality might tempt  you to think of a decorator object as a degenerate composite, but that misses the point of the Decorator pattern. The similarity ends at recursive composition, again because of differing intents.
Decorator is designed to let you add responsibilities to objects without sub-classing. It avoids the
explosion of sub-classes that can arise from trying to cover every combination of responsibilities
statically. Composite has a different intent. It focuses on structuring classes so that many related objects can be treated uniformly, and multiple objects can be treated as one. Its focus is not on embellishment but on representation.

These intents are distinct but complementary. Consequently, the Composite and Decorator patterns are  often used in concert. Both lead to the kind of design in which you can build applications just by
plugging objects together without defining any new classes. There will be an abstract class with some
sub-classes that are composites, some that are decorators, and some that implement the fundamental
building blocks of the system. In this case, both composites and decorators will have a common
interface. From the point of view of the Decorator pattern, a composite is a Concrete Component. From the point of view of the Composite pattern, a decorator is a Leaf. Of course, they don't have to be used together and, as we have seen, their intents are quite different.

Another pattern with a structure similar to Decorator's is Proxy .  Both patterns describe how to
provide a level of indirection to an object, and the implementations of both the proxy and decorator
object keep a reference to another object to which they forward requests. Once again, however, they are  intended for different purposes.

Like Decorator, the Proxy pattern composes an object and provides an identical interface to clients.
Unlike Decorator, the Proxy pattern is not concerned with attaching or detaching properties dynamically,  and it's not designed for recursive composition. Its intent is to provide a stand-in for a subject when it's  inconvenient or undesirable to access the subject directly because, for example, it lives on a remote  machine, has restricted access, or is persistent.

In the Proxy pattern, the subject defines the key functionality, and the proxy provides (or refuses) access  to it. In Decorator, the component provides only part of the functionality, and one or more decorators  furnish the rest. Decorator addresses the situation where an object's total functionality can't be determined at compile time, at least not conveniently. That open-endedness makes recursive composition an essential part of Decorator. That isn't the case in Proxy, because Proxy focuses on one
relationship—between the proxy and its subject—and that relationship can be expressed statically.

These differences are significant because they capture solutions to specific recurring problems in object oriented  design. But that doesn't mean these patterns can't be combined. You might envision a proxy decorator  that adds functionality to a proxy, or a decorator-proxy that embellishes a remote object.  Although such hybrids might be useful (we don't have real examples handy), they are divisible into  patterns that are useful.


Code Examples

Composite


Decorator



Proxy



No comments: