読者です 読者をやめる 読者になる 読者になる

Murayama blog.

プログラミングと、その次の話

Templete Method

新幹線が退屈なのでたまにはRubyのコーディングでも勉強してみます。
もうすぐ新横浜。


ちょっと前に買ってほったらかしにしてたこの本で勉強してみます。
Rubyによるデザインパターン

Rubyによるデザインパターン

Rubyによるデザインパターン


なんとなく「でざいんぱたーん」の響きにやられて衝動買いしてしまった一品。
なんちゃって「デザインパターン」の知識しかない僕には良い復習になるんじゃないかと。
「はっはーん、ふふーん、はいはい、こまんどぱたーんね。」と曖昧な返事しかできないようじゃ厳しいかと。


そんで、第1回はTemplete Method。
プログラムのおおまかな流れをスーパークラスで定義しておいて、
プログラムの変化する部分をサブクラスでオーバーライド実装します。


これは問題ないのでコードだけ。


それはそうと、Rubyの場合、抽象メソッドを定義できないから、
こんなふうに例外を返すメソッドを定義して抽象メソッドとするみたいね。

  def output_head
    raise "Called Abstract method : output_head"
  end


登場するクラス

  • Report
    • レポート出力するクラス。メソッドのテンプレートを定義するクラス。変化する実装はサブクラスでオーバーライドする。
  • HTMLReport
    • HTMLレポートを出力するクラス。Reportのサブクラス。
  • PlainReport
    • プレーンなレポートを出力するクラス。Reportのサブクラス。


report.rb

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_start
  end
  
  def output_head
    raise "Called Abstract method : output_head"
  end
  
  def output_body_start
  end

  def output_body
    @text.each { |line| 
      output_line line
    }
  end
  
  def output_line(line)
    raise "Called Abstract method : output_line"
  end
  
  def output_body_end
  end
  
  def output_end
  end

end


html_report.rb

require "report"
class HTMLReport < Report
  def initialize
    super
  end

  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


plain_report.rb

class PlainReport < Report
  def initialize
    super
  end
  
  def output_head
     puts "*****#{@title}*****"
  end

  def output_line(line)
    puts line
  end
end
  • 実行プログラム(main.rb)
require 'html_Report'
require "plain_report"

puts "HTML REPORT--------"
report = HTMLReport.new
report.output_report

puts "PLAIN REPORT--------"
report = PlainReport.new
report.output_report


実行結果

HTML REPORT--------
<html>
<head>
<title>日記</title>
</head>
<body>
<p>今日は大阪に行ってきました。</p>
<p>天気は晴れでした。</p>
</body>
</html>
PLAIN REPORT--------
*****日記*****
今日は大阪に行ってきました。
天気は晴れでした。