Ruby
デザインパターン

Ruby Strategyパターン

More than 1 year has passed since last update.


はじめに

構造がきれいな設計のために、デザインパターンを再学習しています。

今回はStrategyパターンを扱います。

ちなみに、きれいなコードとはデザインパターンのような構造に関するものと、

リーダブルコードに書いてあるような、読みやすコードの記述方法の2つからなると考えています。


環境

Ruby 2.3.0


概要

振る舞いに関するパターンのひとつで、アルゴリズムを交換できるよう実装します。

「別々のオブジェクトにアルゴリズムを引き出す」テクニックとのこと。

また、Strategyとは英語で「戦略」という意味です。

Strategyパターンを適用するとifをなくすことができます。

コンテキストにもよるので、ケースバイケースですが、

ifなどで分岐してしまうと、複雑になり、可読性も下がります。

理想はifができるだけ少ないプログラムです。


コード1

コード1はクラスの継承による実装です。

継承を使用すると、他に継承できなくなる(多重継承はできない)のと、

アルゴリズムごとにクラスを用意する必要があることがイマイチな気がします。


Strategy.rb

#継承(抽象)クラスを使用したstrategy

class AbstractFormatter
def output
raise "Abstract Method"
end
end

class TextFormatter < AbstractFormatter
def output
puts "text"
end
end

class HtmlFormatter < AbstractFormatter
def output
puts "html"
end
end

class XMLFormatter < AbstractFormatter
def output
puts "XML"
end
end

text = TextFormatter.new
text.output # => text

html = HtmlFormatter.new
html.output # => html

xml = XMLFormatter.new
xml.output # => xml



コード2

コード2はProcオブジェクトを使用した実装で、

よりRubyらしく、アルゴリズムの切り替えも実装できています。


Strategy_lambda.rb

#lambdaを使用したstrategy

class Formatter
def initialize(&formatter)
@formatter = formatter
end

def switch_formatter(&formatter)
@formatter = formatter
end

def output
@formatter.call
end
end

text = -> { puts "text" }
html = -> { puts "html" }
xml = -> { puts "xml" }

formatter = Formatter.new &html
formatter.output # => text

formatter.switch_formatter &text
formatter.output # => html

formatter.switch_formatter &xml
formatter.output # => xml



参考