A number of readers have written to ask why I didn’t cover all of the GoF patterns. There really was a number of reasons. Mainly, there just wasn’t room in the book to cover all 23 patterns and also say all of the things about Ruby that I wanted to say.
I also wanted to try to use each pattern as the context for explaining
some aspect of Ruby programming – so the chapter on the template method
pattern talks about dynamic typing while the chapter on the proxy
pattern explains the
method_missing method. But not all of the GoF
patterns are good vehicles for this kind of discussion. Finally, some
of the GoF patterns – and here the visitor pattern comes
to mind – just don’t make a lot of sense in Ruby.
But if you are curious, here are the GOF patterns I left out and a bit of explanation of why.
The bridge is a a kind of double ended adapter, which completely decouples an abstraction from its implementation. I think of the bridge pattern as more of an antipattern than a pattern. It’s also very rarely used in my experience.
Chain of Responsibility
When you build a chain of responsibiliy, you build a chain of message handlers and send your messages down the chain until you find a handler that can deal with it. I have seen this one used occasionally, but implementing it didn’t really break any new Ruby ground.
A facade is a simple interface to a complex subsystem. If you have ever written a simple wrapper around the
LeftHandedSmokeShiftersubsystem because you only need four of the 862 options that it offers, then you have built a facade. I quite like facades and this pattern is used reasonably often in Ruby: The
Pathnameclass, for example, which is incredibly useful for dealing with paths and filenames is mostly a facade.
Why did I leave the Facade pattern out of the book? Well I almost didn’t – but given the space and time restraints of the book that I was trying to write, the facade got left behind because for two reasons: First, I think that facades come so naturally to good engineers that having me go on about them would not have really added very much. Second, there was nothing that interesting to say about Ruby while talking about the facade that I couldn’t say while talking about adapters or proxies or decorators. And so, the facade, the little pattern that could, got left behind…
But if you are really missing your facades, here are some excerpts from an early draft of the book that did contain a chapter on the facade pattern.
The flyweight pattern allows you to support an apparently large number of objects efficiently by sharing a much smaller number of ‘real’ objects. Another rarely used pattern.
A mediator is an an object which controls the complex interactions between other objects. I have to admit that I don’t have a lot of use for this one.
A Memento captures and externalizes an object’s state in another object. I might have included this one if I had space.
The prototype pattern is a creational pattern along the lines of the factory. The trick with the prototype is that you create new objects by copying a master object. Change that master object and all subsequent objects that you create will go off into life with a copy of the change.
I left the prototype pattern out because I have only ever seen it used once or twice in my career.
The state patterns allows an object to change its behavior when its internal state changes. Largely overtaken by metaprogramming in Ruby.
The visitor pattern lets you define new operations on an existing hierarchical data structure without changing the structure.
Of course, in relatively static languages where changing the code is a big deal, the visitor pattern makes some sense. I’m not sure how useful it is in Ruby: if you need to add an operation to some class or classes in Ruby, well, you just add the operation. Ruby means never having to say, “I’m sorry that class is closed.” The visitor is perhaps my all time least favorite GOF pattern, more like a problem than a solution.