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

理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

Perlでデザインパターンの勉強する

前に言ってたとおり、デザインパターンの勉強をすることに決めました。
参考書は結城先生のこちらの本です!!

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

Javaの開発環境入れるのもメンドいので、perlでやる!
最初はみんな大好きIteratorパターンです!


perlでインタフェースどう実現しよっかなーと思ってたんですけど、interfaceというプラグマがあった。
これはインタフェースで宣言してあるメソッドがきちんと実装クラスで定義してあるか調べてくれる。
実装漏れがあると、

BookShelfIterator is missing methods: next from Iterator at /usr/lib/perl5/site_perl/5.8/interface.pm line 72.
CHECK failed--call queue aborted.

って捨て台詞吐いてアボートしてくれるよ。


あと、もう寝る時間なんで読まずに寝るんだけど、こんなサイトがあった。

ついでにこのモジュールも調べると幸せになれるかもしれないみたい。


Aggregate.pm

package Aggregate;
sub iterator {}
1;

Iterator.pm

package Iterator;

sub has_next {}
sub next {}
1;

Book.pm

package Book;
sub new {
    my ($class, $name) = @_;
    bless { name => $name }, $class;
}

sub get_name { shift->{name} }
1;

BookShelf.pm

package BookShelf;
use interface qw(Aggregate);
use BookShelfIterator;

sub new { bless {}, shift; }

sub get_book_at {
    my $self = shift;
    $self->{books}->[shift]
}

sub append_book {
    my $self = shift;
    push @{ $self->{books} }, @_;
}

sub get_length {
    my $self = shift;
    return scalar @{ $self->{books} };
}

sub iterator {
    return BookShelfIterator->new( shift );
}
1;

BookShelfIterator.pm

package BookShelfIterator;
use interface qw(Iterator);

sub new {
    my ($class, $bookshelf) = @_;
    bless { bookshelf => $bookshelf,
	    index => 0
	  }, $class;
}

sub has_next {
    my $self = shift;
    return $self->{index} < $self->{bookshelf}->get_length();
}

sub next {
    my $self = shift;
    return $self->{bookshelf}->get_book_at( $self->{index}++ );
}    
1;

main.pl

use BookShelf;
use Book;

my $bookshelf = BookShelf->new;
$bookshelf->append_book( Book->new( "hello world" ) );
$bookshelf->append_book( Book->new( "kiririmode" ) );
$bookshelf->append_book( Book->new( "kitoshi" ) );

my $iterator = $bookshelf->iterator;
while( $iterator->has_next() ) {
    my $book = $iterator->next;
    print $book->get_name(), "\n";
}