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)
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
こういった形で共通部分を切り出して抽象化することにより、サブクラスには具体的な内容のみを記述し、プログラムの実行部分は全て親抽象クラスに記述します。
必ずオーバーライドされるべきところにはエラー処理を書いておくと、なお安全性は増しますね。