Template Method
- 作者: Russ Olsen,ラス・オルセン,小林健一,菅野裕,吉野雅人,山岸夢人,小島努
- 出版社/メーカー: ピアソン桐原
- 発売日: 2009/04/01
- メディア: 単行本
- 購入: 13人 クリック: 220回
- この商品を含むブログ (66件) を見る
を買った。
この本は、第 I 部、第 II 部、第 III 部と言う構成になっていて、第 I 部では Ruby という言語について弾丸ツアー(と本に書いてある)で紹介している。
これが第 II 部以降にあるデザインパターンの解説の前に Ruby についてのおさらいとなって、それ以降の内容がとても読みすすめやすくていいなと思った。
第 II 部に読み進めたところで、そこに Ruby で書かれているデザインパターンのコードを理解するために Perl で書き直してみようかなと思った。
本の順番にまず Template Method を Perl で表現してみることにした。
コードを書き直してみて Template Method というのは要するに抽象基底クラスでメソッド群を正にテンプレートのように定義して、各具象クラスでそれらのメソッドをオーバーライドして、おのおのの種類にあった処理を行うというもの、というように理解した。
というわけで以下コード。
抽象基底クラス Report.pm
package Report; use warnings; use strict; sub new { my ($class) = @_; my $self; $self->{title} = '月次報告'; $self->{text} = [ '順調', '最高の調子', ]; return bless($self, $class); } sub output_report { my ($self) = @_; $self->output_start; $self->output_head; $self->output_body_start; $self->output_body; $self->output_body_end; $self->output_end; } sub output_body { my ($self) = @_; my $title = $self->{text}; foreach my $line (@$title){ $self->output_line($line); }; } sub output_start { my ($self) = @_; } sub output_head { my ($self) = @_; $self->output_line($self->{title}); } sub output_body_start { my ($self) = @_; } sub output_line { my ($self, $line) = @_; warn('Called abstract method: output_line'); } sub output_body_end { my ($self) = @_; } sub output_end { my ($self) = @_; } 1;
具象クラス HTMLReport.pm
package Report::HTMLReport; use warnings; use strict; use base 'Report'; sub output_start { my ($self) = @_; print ('<HTML>'); } sub output_head { my ($self) = @_; print ('<HEAD>'); print ('<TITLE>'.$self->{title}.'</TITLE>'); print ('</HEAD>'); } sub output_body_start { my ($self) = @_; print ('<BODY>'); } sub output_line { my ($self, $line) = @_; print ('<p>'.$line.'</p>'); } sub output_body_end { my ($self) = @_; print ('</BODY>'); } sub output_end { my ($self) = @_; print ('</HTML>'); } 1;
具象クラス PlainTextReport.pm
package Report::PlainTextReport; use warnings; use strict; use base 'Report'; sub output_head { my ($self) = @_; print ('**** '.$self->{title}." ****\n"); } sub output_line { my ($self, $line) = @_; print ($line); } 1;
使用例
#!/usr/bin/perl use Report::HTMLReport; use Report::PlainTextReport; my $report; $report = Report::HTMLReport->new; $report->output_report; $report = Report::PlainTextReport->new; $report->output_report;
これ以降のパターンも、気が向いたら書き直してみようかなとおもった。