「Rubyによるデザインパターン」の読書メモです。
時々、個人の見解入りです。
修正前
例えば下記のようなコードがあったとします。
ここから、htmlではなくプレーンテキスト形式でもレポートを表示する要件が加わったとき、どうすれば良いでしょうか。
class Report
def initialize
@title = '月次報告'
@text = ['順調', '最高']
end
# 簡略化
def output_report
puts('<html>')
puts("<title>#{@title}</title>")
@text.each do |line|
puts("<p>#{line}</p>")
end
puts('</html>')
end
end
Report.new.output_report
修正後
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
private
def output_body
@text.each do |line|
output_line(line)
end
end
def output_start
end
def output_head
output_line(@title)
puts
end
def output_body_start
end
def output_line(line)
raise "Called abstract method: #{__method__}"
end
def output_body_end
end
def output_end
end
end
class HTMLReport < Report
private
def output_start
puts '<html>'
end
def output_head
puts "<head><title>#{@title}</title></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
class PlainTextReport < Report
private
def output_line(line)
puts(line)
end
end
p '-- HTMLReport --'
HTMLReport.new.output_report
p '-- PlainTextReport --'
PlainTextReport.new.output_report
これで新しいフォーマットが必要になった場合も、サブクラス追加で出来ますね。
※ 本のサンプルコードに少し手を加えています。
おまけ
ダックタイピング
「もしアヒルのように見えて、アヒルのように鳴くのなら、それはアヒルである」
注意点
すべての起こりうる事態に対処するために、サブクラスに大量のメソッドをオーバーライドさせるようなテンプレートクラスを作成するのは避けましょう。