Posted at

Rubyデザインパターン 1日目 : Template Method

More than 3 years have passed since last update.

Rubyデザインパターン学習のために、自分なりに読書の結果をまとめていくことに決めました。第1日目はTemplateMethodです。(http://www.amazon.co.jp/gp/product/4894712857/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4894712857&linkCode=as2&tag=morizyun00-22)

スクリーンショット 2015-07-27 11.25.28.png


1日目 Template Method

Template Methodとは最も基本的なデザインパターンと言われており、Template Methodを構築するというよりは、便利なコードにリファクタリングしていくと、自然とTemplate Method型になっていくことがよくあるそうです。

Template Methodの目的は、変わる物と変わらない物を分離し、その変わらない部分を抽象化したスーパークラスを作成してテンプレートとします。サブクラスではそれを継承することにより、コードの重複を無くし、メンテナンス性も高めることが出来ます。

大事なのは、デザインパターンを適用するためにコードを書くのではなく、必要になったときに少しずつ実装していくのがいいとのことです。そうでなければ、特定のデザインパターンを適用する為に、コードを書きかねないとのこと。

書籍の内容に沿って、HTMLを出力するクラスと、平文を出力するクラスをTemplate Methodで表現していきます。


抽象クラス

class Report

def initialize
@title = '月次報告'
@text = ['順調', '最高の調子']
end

def output_report
output_start
output_head
output_body_start
output_body
output_body_end
output_end
end

def output_body
@text.each do |line|
output_line(line)
end
end

def output_start
end

def output_head
raise 'Called abstract method: output_head'
end

def output_body_start
end

def output_line(line)
raise 'Called abstract method: output_body'
end

def output_body_end
end

def output_end
end
end


平文を出力するサブクラス

class PlainTextReport < Report

def output_head
puts "****#{@title}****"
end

def output_line(line)
puts line
end
end

report_plain = PlainTextReport.new
report_plain.output_report


HTMLを出力するサブクラス

class HTMLReport < Report

def output_start
puts ('<html>')
end

def output_head
puts ('<head>')
puts ("<title>#{@title}</title>")
puts ('</head>')
end

def output_body_start
puts ('<body>')
end

def output_line(line)
puts (" <p>#{line}</p>")
end

def output_body_end
puts ('</body>')
end

def output_end
puts ('</html>')
end
end

report_html = HTMLReport.new
report_html.output_report

こういった形で共通部分を切り出して抽象化することにより、サブクラスには具体的な内容のみを記述し、プログラムの実行部分は全て親抽象クラスに記述します。

必ずオーバーライドされるべきところにはエラー処理を書いておくと、なお安全性は増しますね。