PerlでBuilderパターン! (デザインパターン)
Perlでデザインパターン 第7弾(Builderパターン)
Builderパターンとは、Director(監督)の管理下、Builder(親方)が作成項目だけ指示して、ConcreteBuilder(大工) に Building(家) インスタンスを生成させるデザインパターンです。
また、BuilderとConcreteBuilderの関係は、Templateパターンになっていますね。
一般的なBuilderパターンのクラス図
関連 集約 +---------------+ +---------------+ +---------------+ | Client |----->| Director |o---->| Builder | +---------------+ +---------------+ +---------------+ | | | builder | | | +---------------+ +---------------+ +---------------+ | | | construct | | buildPart1 | | | | | | buildPart2 | | | | | | buildPart3 | +-------+-------+ +---------------+ +---------------+ | # | | 継承 | | | +-------+-------+ +------------------------------------>|ConcreteBuilder| +---------------+ | | +---------------+ |buildPart1 | |buildPart2 | |buildPart3 | |getResult | +---------------+
サンプル
一番下で紹介している本の『Java言語で学ぶデザインパターン入門』に書かれているBuilderパターンのJavaでのサンプルをPerlで書き換えてみました。
サンプルのクラス図
+---------------+ +---------------+ +--------------+ | Main |---->| Director |o--->| Builder | +---------------+ +---------------+ +--------------+ | | | builder | | | +---------------+ +---------------+ +--------------+ | | | construct | | makeTitle | | | | | | makeString | | | | | | makeItems | | | | | | close | +-------+-------+ +---------------+ +--------------+ | # | | 継承 | +----------+----------+ | | | | +-------+-------+ +-------+-------+ | | TextBuilder | | HTMLBuilder | | +---------------+ +---------------+ | | buffer | | filename | | +---------------+ | writer | | | makeTitle | +---------------+ | | makeString | | makeTitle | | | makeItems | | makeString | | | close | | makeItems | | | getResult | | close | | | | | getResult | | +---------------+ +---------------+ | ^ ^ | | | +--------------------------------+---------------------+
Builder.pm
package Builder; use strict; use warnings; sub makeTitle { die "オーバーライド必須"; } sub makeString { die "オーバーライド必須"; } sub makeItems { die "オーバーライド必須"; } sub close { die "オーバーライド必須"; } 1;
Director.pm
package Director; use strict; use warnings; sub new { my $class = shift; my $self = {}; $self->{builder} = shift; return bless $self, $class; } sub construct { my $self = shift; $self->{builder}->makeTitle('Greeting'); $self->{builder}->makeString('朝から昼にかけて'); $self->{builder}->makeItems([ 'おはようございます。', 'こんにちは。', ]); $self->{builder}->makeString('夜に'); $self->{builder}->makeItems([ 'こんばんは。', 'おやすみなさい。', 'さようなら。', ]); return $self->{builder}->close; } 1;
TextBuilder.pm
package TextBuilder; use strict; use warnings; use base 'Builder'; sub new { my $class = shift; my $self = {}; $self->{buffer} = ''; return bless $self, $class; } sub makeTitle { my $self = shift; my $title = shift; $self->{buffer} .= "===========================\n"; $self->{buffer} .= "『$title』\n\n"; } sub makeString { my $self = shift; my $str = shift; $self->{buffer} .= "■$str\n\n"; } sub makeItems { my $self = shift; my $items = shift; for my $i (0..$#{$items}) { $self->{buffer} .= " ・$items->[$i]\n"; } $self->{buffer} .= "\n"; } sub close { my $self = shift; $self->{buffer} .= "==========================\n"; } sub getResult { my $self = shift; return $self->{buffer}; } 1;
HTMLBuilder.pm
package HTMLBuilder; use strict; use warnings; use FileHandle; use base 'Builder'; sub new { my $class = shift; my $self = {}; $self->{filename} = ''; $self->{writer} = ''; return bless $self, $class; } sub makeTitle { my $self = shift; my $title = shift; $self->{filename} = $title.".html"; $self->{writer} = FileHandle->new("> $self->{filename}"); $self->{writer}->print("<html><head><title>$title</title></head><body>\n<h1>$title</h1>\n"); } sub makeString { my $self = shift; my $str = shift; $self->{writer}->print("<p>$str</p>\n"); } sub makeItems { my $self = shift; my $items = shift; $self->{writer}->print("<ul>\n"); for my $i (0..$#{$items}) { $self->{writer}->print("<li>$items->[$i]</li>\n"); } $self->{writer}->print("</ul>\n"); } sub close { my $self = shift; $self->{writer}->print("</body></html>\n"); $self->{writer}->close; } sub getResult { my $self = shift; return $self->{filename}; } 1;
Main.pl
use strict; use warnings; use Director; use TextBuilder; use HTMLBuilder; my ($args) = @ARGV; $args = "" if (!defined($args)); if ($args eq 'plain') { my $TextBuilder = TextBuilder->new; my $director = Director->new($TextBuilder); $director->construct; my $result = $TextBuilder->getResult; print $result; } elsif ($args eq 'html') { my $HTMLBuilder = HTMLBuilder->new; my $director = Director->new($HTMLBuilder); $director->construct; my $filename = $HTMLBuilder->getResult; print "$filenameが作成されました。\n"; } else { &usage; } sub usage { print "Usage: perl Main.pl plain プレーンテキストで文書作成\n"; print "Usage: perl Main.pl html HTMLファイル文書作成\n"; }
実行結果
C:\Documents and Settings\dp\Builder>perl Main.pl plain =========================== 『Greeting』 ■朝から昼にかけて ・おはようございます。 ・こんにちは。 ■夜に ・こんばんは。 ・おやすみなさい。 ・さようなら。 ==========================
C:\Documents and Settings\dp\Builder>perl Main.pl html Greeting.htmlが作成されました。 C:\Documents and Settings\dp\Builder>type Greeting.html <html><head><title>Greeting</title></head><body> <h1>Greeting</h1> <p>朝から昼にかけて</p> <ul> <li>おはようございます。</li> <li>こんにちは。</li> </ul> <p>夜に</p> <ul> <li>こんばんは。</li> <li>おやすみなさい。</li> <li>さようなら。</li> </ul> </body></html>
尚、本コンテンツは、結城先生の以下の本をかなり参考にしています。
Javaでデザインパターンを勉強したい人には、お勧めのご著書です!
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/06/19
- メディア: 大型本
- 購入: 51人 クリック: 762回
- この商品を含むブログ (400件) を見る