Skip to content

Instantly share code, notes, and snippets.

@nastysloper
Created May 30, 2013 00:53
Show Gist options
  • Save nastysloper/5675072 to your computer and use it in GitHub Desktop.
Save nastysloper/5675072 to your computer and use it in GitHub Desktop.

Strategy Pattern

The Strategy pattern is a delegation-based approach to solving the same problem as the Template Method pattern -- instead of breaking up the variable parts of your algorithm and implementating those parts in subclasses, you simply implement each version of your algorithm as a separate object. You can then vary the algorithm by supplying different strategy objects to the context.

The Strategy Pattern consists of strategies, which are interchangeable classes which encapsulate varieties of a particular algorithm, and the context class, which utilizes strategies. The context can choose different strategies depending on the situation.

Here are a couple code examples illustrating the Strategy Pattern:

# strategy class
class HtmlFormatter
  def output_report(title, text)
    puts "<h1>#{title}</h1>"
    puts "<p>#{text}</p>"
  end
end

# strategy class
class PlainTextFormatter
  def output_report(title, text)
    puts "***** #{title} *****"
    puts text
  end
end

# context class
class Report
  attr_reader :title, :text
  attr_accessor :formatter

  def initialize(formatter)
    @title = 'Monthly Report'
    @text =  'Going great!'
    @formatter = formatter
  end

  def output_report
    @formatter.output_report(@title, @text)
  end
end

report = Report.new(PlainTextFormatter.new)
report.output_report

report.formatter = HtmlFormatter.new
report.output_report

The Strategy Pattern can also be implemented using procs:

class Duck
  attr_reader :name
  attr_accessor :chirper

  def initialize(&strategy)
    @name = "Donald"
    @chirper = strategy
  end

  def chirp
    @chirper.call(self)
  end
end

QUACK_CHIRPER = lambda do |context|
  puts "Quack, my name is #{context.name}"
end

duck = Duck.new &QUACK_CHIRPER
duck.chirp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment