01032007 designpattern デザパタ
Kwikiで使われているSpiffyが気になったので テンプレートメソッドを書いてみた。
-Baseで継承すると、$self=shiftとパッケージの最後に1;をつけなくてもよくなるので、コード量が減るらしい
AbstractDisplay.pm
package AbstractDisplay; use Spiffy -Base; stub 'open'; stub 'print'; stub 'close'; sub display { $self->open; for my $i (0..4) { $self->print; } $self->close; }
CharDisplay.pm
package CharDisplay; use AbstractDisplay -Base; sub new { my $char = shift; bless {ch => $char}, $self; } sub open { print "<<"; } sub print { print "$self->{ch}"; } sub close { print ">>\n"; }
StringDisplay.pm
package StringDisplay; use AbstractDisplay -Base; sub new { my $str = shift; my $w = length($str); bless { string => $str, width => $w }, $self; } sub open { $self->_printline; } sub print { print "|$self->{string}|\n"; } sub close { $self->_printline; } sub _printline { print "+"; for my $i (0..$self->{width}-1) { print "-"; } print "+\n"; }
main.pl
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/usr/bin/perl use strict; use CharDisplay; use StringDisplay; my $d1 = CharDisplay->new('H'); my $d2 = StringDisplay->new("Hello, World."); my $d3 = StringDisplay->new("るるるるる"); $d1->display; $d2->display; $d3->display; |
で実行してみる。
<<HHHHH>> +-------------+ |Hello, World.| |Hello, World.| |Hello, World.| |Hello, World.| |Hello, World.| +-------------+ +---------------+ |るるるるる| |るるるるる| |るるるるる| |るるるるる| |るるるるる| +---------------+
抽象クラスのstubは実装をサブクラスに任すときに使う。サブクラスで実装されてないとdieする。
試しに、CharDisplayのprintメソッドがないと
Method print in package AbstractDisplay must be subclassed at \ /usr/lib/perl5/site_perl/5.8.8/Spiffy.pm line 279 Spiffy::__ANON__('CharDisplay=HASH(0x9a49c28)') \ called at AbstractDisplay.pm line 12 AbstractDisplay::display('CharDisplay=HASH(0x9a49c28)') \ called at ./main.pl line 11
とエラー吐いてとまる。
コードの見通しは良くなる感じ(もうちょっと複雑なことやってみないと分からんけど。)