We are a software consultancy based in Berlin, Germany. We deliver
high quality web apps in short timespans.

Upstream Agile GmbH

Implementation Patterns emerging

December 03, 2007 by alex

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:

class Video
  def initialize(url)
    @url = url
  end

  def html
    if @url.include?('youtube.com')
      "<embed>player.youtube.com/#{@url}</embed>"
    elsif @url.include?('vimeo')
      "<embed>vimdeo.com/player/#{@url}/1</embed>"
    end
  end
end

Using the selector pattern it might look like this:

class Video
  @@renderers = {
    'youtube.com' => lambda{|url| "<embed>player.youtube.com/#{url}</embed>"},
    'vimeo' => lambda{|url| "<embed>vimdeo.com/player/#{url}/1</embed>"}
  }

  def initialize(url)
    @url = url
  end

  def html
    select_provider.call(@url)
  end

  private

  def select_provider
    @@renderers.select{|provider, code| @url.include?(provider)}.first.last
  end
end

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.