Template Method
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/06/19
- メディア: 大型本
- 購入: 51人 クリック: 762回
- この商品を含むブログ (397件) を見る
AbstractDisplayクラス
package AbstractDisplay; use Moose::Role; requires qw/open print close/; sub display { my $self = shift; $self->open; for (1 .. 5) { $self->print; } $self->close; }
AbstractDisplayクラスは、displayメソッドで、open,print,closeのそれぞれのメソッドの呼び出し方を定義している。open,print,closeメソッドの定義については、継承先に任せている。
Mooseで抽象クラスを作るには、
use Moose::Role;
と書き、packageを定義する。
抽象メソッドを指定するには、
requires qw/open print close/;
と書く。これにより、継承先ではopen,print,closeメソッドを定義するように強制できる。定義しないとコンパイルエラーになる。
CharDisplayクラスとStringDisplayクラス
AstractDisplayクラスを継承して、それぞれ違う動作をするCharDisplayクラスとStringDisplayクラスを定義する。まずはCharDisplayクラス。
package CharDisplay; use Moose; with 'AbstractDisplay'; has ch => ( is => 'rw', isa => 'Str', required => 1, ); sub open { print "<<"; } sub print { my $self = shift; print $self->ch; } sub close { print ">>\n"; } package main; my $o_char = CharDisplay->new(ch => "t"); $o_char->display;
実行結果がこちら。
<
>
AbstractDisplayクラスの継承は、
with 'AbstractDisplay';
という記述で行なう。
charDisplayクラスでは、ch属性をhasで定義している。
has ch => ( is => 'rw', # この属性は読み書き機能 isa => 'Str', # この属性に設定できる型はStr(文字列)だけである required => 1, # オブジェクト生成時に値をセットする必要がある );
これは「アトリビュート(属性)コンストラクタ」と呼ばれ、属性について制限がかけられる。ここでは「required => 1」に指定されているので、オブジェクト生成時に
my $o_char = CharDisplay->new( ch => 't' );
と行った感じで、ch属性の値をセットしている。
次にStringDisplayクラスの実装。
package StringDisplay; use Moose; with 'AbstractDisplay'; has string => ( is => 'rw', isa => 'Str', required => 1, ); sub open { my $self = shift; $self->printLine(); } sub print { my $self = shift; print '|' . $self->string . '|' . "\n"; } sub close { my $self = shift; $self->printLine(); } sub printLine { my $self = shift; my $width = length $self->string; print '+'; for (1 .. $width) { print '-'; } print "+\n"; } package main; my $o_string = StringDisplay->new(string => "hato test"); $o_string->display;
実行結果は、
- +
hato test hato test hato test hato test hato test
- +
以上。
デザインパターンを実装すると、なんか気持ちいいな。