TemplateMethod パターン Ruby
TemplateMethodパターン
テンプレートメソッドパターンとは
抽象的な処理と具体的な処理を分離することで、 変化に強い構造を実現する。
2つのオブジェクトによって構成される。
- 骨格としての「抽象的なベースクラス」
- 実際の処理を行う「サブクラス」
用いるメリット
- 抽象的なベースクラス側に、「変わらない基本的なアルゴリズム」を置ける
- 抽象的なベースクラスは「高レベルの処理」を制御することに集中出来る
- サブクラス側に、「変化するロジック」を置ける
- サブクラスは「詳細を埋めること」に集中出来る
実装
- Report(抽象的なベースのクラス): レポートを出力する
- HTMLReport(サブクラス): HTMLフォーマットでレポートを出力
- PlaneTextReport(サブクラス): PlanTextフォーマットでレポートを出力
ベースとなるクラス
class Report def initialize @title = "html report title" @text = ["report line 1", "report line 2", "report line 3"] end # レポートの出力手順を規定 def output_report output_start output_body output_end end # レポートの先頭に出力 def output_start raise NotImplementedError end # レポートの本文の管理 def output_body @text.each do |line| output_line(line) end end
具体的な処理を実装したサブクラス
HTMLReport
class HTMLReport < Report # レポートの先頭に出力 def output_start puts "<html><head><title>#{@title}</title></head><body>" end # 本文内のLINE出力部分 def output_line(line) puts "<p>#{line}</p>" end # レポートの末尾に出力 def output_end puts '</body></html>' end end
PlaneTextReport
class PlaneTextReport < Report # レポートの先頭に出力 def output_start puts "**** #{@title} ****" end # 本文内のLINE出力部分 def output_line(line) puts line end end
実行
html_report = HTMLReport.new html_report.output_report #<html><head><title>html report title</title></head><body> #<p>report line 1</p> #<p>report line 2</p> #<p>report line 3</p> #</body></html> plane_text_report = PlaneTextReport.new plane_text_report.output_report #**** html report title **** #report line 1 #report line 2 #report line 3
変わるもの(具象サブクラス)と変わらないもの(テンプレート)を分離して、変化に強い構造へ。
具象クラスによってオーバーライド出来る(不要ならしなくてもよい)メソッドのことを、 フックメソッドと呼ぶ
凡化 = 抽象化
特化 = 具象化