LoginSignup
13
17

More than 5 years have passed since last update.

Strategy パターン

Last updated at Posted at 2014-07-26

アルゴリズムを実行時に選択することができるデザインパターンである。

使い道

  • Template Method パターン と同じ
  • ただし、Template Method パターン の時に書いたような定形のプロトコルに沿った実装ではなく、個別に柔軟な実装を書きたい時に使う感じか

実装

StringLister#display の挙動を、Strategy のサブクラスに移譲している
これにより、コンストラクタの引数で、StringLister#display の挙動が柔軟に変えられるようになる

strategy.rb
class StringLister
  attr_reader :items
  def initialize(items, strategy)
    @items = items
    @strategy = strategy
  end

  def display
    @strategy.display(@items)
  end
end

class Strategy
  def display(items)
    raise NotImplementedError
  end
end

class TextStrategy
  def display(items)
    items.join("\n")
  end
end

class HtmlStrategy
  def display(items)
    result = []
    result << "<html><body>"
    items.each{|item| result << "<div>#{item}</div>" }
    result << "</body></html>"
    result.join("\n")
  end
end

items = %w[abc def ghi]
puts StringLister.new(items, HtmlStrategy.new).display
# <html><body>
# <div>abc</div>
# <div>def</div>
# <div>ghi</div>
# </body></html>

puts StringLister.new(items, TextStrategy.new).display
# abc
# def
# ghi

より、Ruby 風な書き方

StringLister のコンストラクタに、Strategy のサブクラスではなく、block を渡す
こっちの方が、いちいちクラスを定義する必要がなく、より柔軟な書き方ができる

strategy.rb
class StringLister
  attr_reader :items
  def initialize(items, &strategy)
    @items = items
    @strategy = strategy
  end

  def display
    @strategy.call(@items)
  end
end


items = %w[abc def ghi]

disp = StringLister.new(items) do |items|
  result = []
  result << "<html><body>"
  items.each{|item| result << "<div>#{item}</div>" }
  result << "</body></html>"
  result.join("\n")
end.display
puts disp

# <html><body>
# <div>abc</div>
# <div>def</div>
# <div>ghi</div>
# </body></html>

disp = StringLister.new(items) do |items|
  items.join("\n")
end.display
puts disp

# abc
# def
# ghi

雑感

多分だけど、関数をオブジェクトにしたいが為のパターンなのかな?

  • C++ は、関数が第一級オブジェクトでない

参考

13
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
17