Some patterns are so good they become part of the way that people think about systems. They get implemented using general solutions and then people just use them as a piece of technology. In these cases, a modern developer is himself unlike to implement the pattern, he’s much more likely to just use the libraries that implement the pattern. I’m terming these infrastructure patterns.
Proxy and Decorator
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.
In many ways, 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 one of intent. We call it a decorator if it modifies functionality, or a proxy if it doesn’t.
You can do quite a few things with a proxy/decorator:
- 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, quite a lot of the time the boundary between the two terms is blurred. It’s usually called a proxy if you’re crossing a system boundary, but if you’re checking permissions? Strictly it’s a decorator.
In practice, most of your needs for true 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.
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.
For large APIs such as System.IO.Stream, it’s rarely advisable to do this stuff by hand, because delegating methods is both dull and error prone.
Steve Yegge pointed out that this pattern basically just works around a deficiency in the design of C++. In C#, it’s the foreach statement. Call it iterator if you want, I tend to call it IEnumerable.
An interpreter is a language that is executed without going through a compilation state. The interpreter pattern is basically the same. Now, there’s basically two cases in which you’d be hit with this as a requirement:
- You’ve been provided with an external language specification that you need to parse and process.
- You need to create a small language to deal with a particularly flexible requirement.
In the first case, it doesn’t matter what you do, you’re writing an interpreter or compiler. Since anything you did could be described as matching the interpreter pattern, it’s hard to see how useful the terminology is. Interpreter was a term of art in the 1960s, not a design pattern in the 80s.
In the second case, you’re writing a DSL. And here, frankly, I wouldn’t use an interpreter. Most modern thinking on this subject says that you’re better off using a language that already exists and tweaking it to your purpose.
The most obvious language choices are IronPython, IronRuby or Boo.
- IronPython has a relatively inflexible syntax, but it’s extremely sophisticated and can be happily used for scripting purposes.
- IronRuby (and Ruby in general) is the most popular DSL base language in the world, with a very flexible syntax. It’s not as mature as IronPython, though, which may put you off.
- Boo has a customizable syntax, is mature and is open source. However, it’s syntax is possibly over-flexible, to the extent that it can be very hard to figure out what a DSL does without reading its source code. You can mitigate this by writing decent documentation, but typically DSLs don’t come with much.
The iterator and interpreter patterns are both terminology that ought to be retired. This is not to say they’re bad patterns, it’s just that it’s not useful to name the concepts anymore. The term “interpreter” is best used simply to denote the same concept it represented in the 1960s: runtime evaluation of a programming language. The proxy pattern is something you’re highly unlikely to need to implement yourself, but it’s extremely important you understand the concept it represents and when your code is using proxies. Decorator is just a proxy that modifies behaviour. You’re actually quite likely to implement your own decorators, though.
UPDATE: The text about decorators has been revised. The original text can be found here.