Implementation Patterns emerging
I recently read Kent Beck’s new book Implementation Patterns - it was a nice read and I guess it somehow strengthened my senses towards patterns a bit. Unfortunately it is written with Java in mind, and as we all know Patterns are language specific. The following can’t really be applied to Java as far as i know (having stopped writing in Java with 1.5).
So I discovered a kind of implementation pattern I had used a few times in the last weeks. Maybe everyone has already written about it but I want to stress that I discovered it myself
Here it is:
The Selector Pattern
When to use it: When you have a complicated if-elseif-elsif-else or switch clause and want to replace it with something more elegant.
When not to use it: It works well for limited complexity. I things get more complex you may want to use class inheritance instead.
What it does: Put the each condition and the according logic into a hash. Then iterate through the conditions to find a match and execute its logic.
Example
Suppose you have a class Video that represents a video on youtube or some other hosting provider. Its purpose is to render the neccessary HTML tags to embed it into a document. The generated HTML differs depending on the hosting provider, e.g. youtube.com or vimeo.com. The code could be expressed like this:
Using the selector pattern it might look like this:
With only 2 providers this doesn’t make too much sense but with something like 5 your elsifs start to get really ugly and the selector pattern offers a more ligtweight way to replace these than creating an entire hierarchy of subclasses for every case.
Tags: implementation-patterns, patterns, programming, ruby




December 27th, 2007 at 1:26 pm
Ruby offers you a more elegant way of doing this. Remember: an object is more or less a hash matching ids to Proces. So your code could be
class Video
class Renderers
def self.youtube(url)
"player.youtube.com/#{url}"
end
def self.vimeo(url)
"vimdeo.com/player/#{url}/1"
end
end
def html
renderers = self.class.Renderers
provider = renderers.public_methods.
find { |met| @url.include?(met)}
renderers.send provider, @url
end
end
2 lines less, no ugly lambdas, no Proc object (which makes that thing faster), Ruby class magic still possible etc.
You could even embed the actual renderers into a module which you would then mix into the Video class: no need to pass url any longer
BTW: It appears your code iterates over *all* renderers, not only over the first one.
See you @ CCC?
December 27th, 2007 at 1:28 pm
Having at least one way to insert actual code here and/or some kind of preview: *that* would be great. I would even trade in smileys
December 27th, 2007 at 6:07 pm
Nice idea, although I think this gets close to overengineering, but that’s just my personal taste. The problem with this is that in the meantime we have changed the keys in the hash to regular expressions and now using method names would not work anymore. What we could do now is to use blocks again instead of methods:
class Renderers
renderer /video\.google\.(de|com)/ do |url|
"video.google.com/${url}"
end
end
This should probably build up another Hash again but then we surely end up with overengineered code. But expressive. Maybe.
(any suggestions for comment preview/code plugins for wordpress?)
December 28th, 2007 at 12:58 pm
I like that, this last one is quite expressive…