This article contains text I originally wrote for the Gang of Four Patterns thread. I’m keeping the old text here, along with notes about why I was wrong.
The Composite Pattern
REMOVED: Actually, the composite pattern is a lot more useful than this, I rethought my remarks later. With this and the decorator pattern, I realized that I used the concept a lot, I just didn’t use the terminology. In the case of composite, I think this is actually quote common.
Whilst the visitor pattern isn’t about tree structures, but most people think it is, the composite pattern is about tree structures, and most people don’t know about it. The principle is very simple: when you’ve got a tree structure, provide an interface that is implemented by both leaves and branches of the tree. This enables you to manipulate parts of the tree easily. A classic example of this is the Xml Document structure, where attributes and elements both expose the XmlNode interface. Another would be semantic evaluation of expression trees. You’ll need to use this if you’re writing a compiler.
It’s a useful concept, if a bit special case. The truth is uniform (or uniform-able) tree structures are more rare than Computer Science lectures would suggest.
Proxy and Decorator
ALTERED: The original text fairly strongly argued that the distinction between proxy and decorator was meaningless. The revised text tones this down, since I’ve realized the terminology is more useful than I thought.
A modern developer lives with proxy objects the whole time. If you have an object X, a proxy for object X behaves is an object that exposes the same interface as X and delegates calls through to X. You can do quite a few things with a proxy:
- NHibernate uses entity proxies to allow objects to be lazily loaded.
- You could use Castle DynamicProxy to log all calls to a destination object.
- Equally, you could a use a proxy to restrict access and add a permissioning system.
- You use client proxies in WCF to make it look like you’re calling a service directly. In practice, you call a proxy, the proxy performs network communication with the server and then the server calls the real object.
In practice, most of your needs for proxy objects are handled by framework libraries. Those that aren’t, I recommend using a general proxy solution like DynamicProxy. Krzysztof has written an excellent tutorial. However, just because you’re not implementing proxies yourself, it doesn’t mean you don’t need to know what one is. On the other hand, most modern developers do understand this stuff already, because much of what we write these days involves some form of remote component.
To be honest, Decorator and Proxy are the same pattern. If you don’t believe me, check the UML diagrams on Wikipedia (this from the guy who hates UML). The major difference is usually one of intent. A decorator is a proxy that is meant to add functionality. So, from the examples I gave, the option of logging calls could be described as a decorator pattern, but seriously, is it useful to do so? The classic example of the decorator pattern in the .NET Framework is the IO library (it pretty much copies Java’s approach). In the call “new BufferedStream(stream)”, the BufferedStream is a decorator that buffers the calls to the underlying stream. It’s exactly the same as the original stream, except that it’s buffered. But it’s just a proxy, really.
It’s rarely worth doing this stuff by hand, because delegating methods is both dull and error prone.