小池啓仁 ヒロヒト応援ブログ By はてな

小池啓仁(コイケヒロヒト)の動画など。

小池啓仁 ヒロヒト応援ブログ By はてな

Perlでイテレータパターン! (デザインパターン)

Perlデザインパターン 第1弾(イテレータパターン)

かつて、Java言語でデザインパターンを勉強したメモが以下のリンクにあります。

今回、Perlでリメイクしてみました。第一弾は、「Perlイテレータパターン!」です。
尚、オブジェクト指向の基礎とイテレータパターンの解説は、上記のリンクを読んでください。
また、Perlでのオブジェクト指向の解説は下記のリンクを読んでください。

イテレータサンプルのクラス図

     +---------------------+                 +-------------------+
     | Aggregate           |---------------->| Iterator          |
     +---------------------+                 +-------------------+
     |                     |                 |                   |
     |  iterator()         |                 | hasnext()         |
     |                     |                 | next()            |
     |                     |                 |                   |
     +---------------------+                 +-------------------
                #                                      #
                |                                      |
                |                                      |継承
                |                                      |
     +----------+----------+                 +---------+---------+
     | 部品棚              |<---------------O| 部品イテレータ    |
     +---------------------+                 +-------------------+
     | buhins              |                 | aggregate         |
     | last                |                 +-------------------+
     +---------------------+                 |                   |
     | addBuhin()          |                 | hasnext()         |
     |                     |                 | next()            |
     |                     |                 |                   |
     +---------------------+                 +-------------------+
                O
                |
                |集約
                V
     +----------+----------+
     | 部品                |
     +---------------------+
     | name                |
     +---------------------+
     | getname()           |
     |                     |
     +---------------------+

イテレータサンプルのプログラムソース

では、以下で、イテレータパターンのJavaPerlでのソースの違いをご確認ください。
尚、Javaのソースは「オブジェクト指向 WITH JAVA」のと同じです。

Aggregateインターフェイス

Aggregate.java

public interface Aggregate {
    public abstract Iterator iterator();
}

Aggregate.pm

package Aggregate;
use strict;
sub iterator{die "オーバーライド必須";}
1;
Iteratorインターフェイス

Iterator.java

public interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();
}

Iterator.pm

package Iterator;
use strict;
sub  hasNext{die "オーバーライド必須";}
sub  next{die "オーバーライド必須";}
1;
部品イテレータクラス

BuhinIterator.java

public class BuhinIterator implements Iterator {
    private Buhindana buhindana;
    private int index;
    public BuhinIterator(Buhindana buhindana) {
        this.buhindana = buhindana;
        this.index = 0;
    }
    public boolean hasNext() {
        if (index < buhindana.getLength()) {
            return true;
        } else {
            return false;
        }
    }
    public Object next() {
        Buhin buhin = buhindana.getBuhinAt(index);
        index++;
        return buhin;
    }
}

BuhinIterator.pm

package BuhinIterator;
use strict;
use base 'Iterator';
    sub new {
        my $class = shift;
        my $buhindana = shift;
        return bless { buhindana => $buhindana, index => 0} , $class;
    }
    sub hasNext {
       my $self = shift;
       if ($self->{index} < $self->{buhindana}->getLength()) {
            return 1;
        } 
        else {
            return 0;
        }
    }
    sub  next {
        my $self = shift;
        my $buhin = $self->{buhindana}->getBuhinAt($self->{index});
        $self->{index}++;
        return $buhin;
    }
1;
部品棚クラス

Buhindana.java

public class Buhindana implements Aggregate {
    private Buhin[] buhins;
    private int last = 0;
    public Buhindana(int maxsize) {
        this.buhins = new Buhin[maxsize];
    }
    public Buhin getBuhinAt(int index) {
        return buhins[index];
    }
    public void addBuhin(Buhin buhin) {
        this.buhins[last] = buhin;
        last++;
    }
    public int getLength() {
        return last;
    }
    public Iterator iterator() {
        return new BuhinIterator(this);
    }
}

Buhindana.pm

package Buhindana;
use strict;
use base 'Aggregate';
use BuhinIterator;
    sub  new {
        my $class = shift;
        return bless {buhins => [], last =>0}, $class
    }
    sub getBuhinAt {
        my $self = shift;
        my $index = shift;
        return $self->{buhins}[$index];
    }
    sub addBuhin {
        my $self = shift;
        my $buhin = shift;
        $self->{buhins}[$self->{last}] = $buhin;
        $self->{last}++;
    }
    sub getLength {
        my $self = shift;
        return $self->{last};
    }
    sub iterator {
        my $self = shift;
        return BuhinIterator->new($self);
    }
1;
部品クラス

Buhin.java

public class Buhin {
    private String name = "";
    public Buhin(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

Buhin.pm

package Buhin;
use strict;
    sub  new {
        my $class = shift;
        my $name = shift;
        return bless {name => $name}, $class;
    }
    sub getName {
        my $self = shift;
        return $self->{name};
    }
1;
メインクラス

Main.java

public class Main {
    public static void main(String[] args) {
        Buhindana buhindana = new Buhindana(4);
        buhindana.addBuhin(new Buhin("CPU"));
        buhindana.addBuhin(new Buhin("メモリ"));
        buhindana.addBuhin(new Buhin("マザーボード"));
        buhindana.addBuhin(new Buhin("ハードディスク"));
        Iterator it = buhindana.iterator();
        while (it.hasNext()) {
            Buhin buhin = (Buhin)it.next();
            System.out.println("" + buhin.getName());
        }
    }
}

Main.pl

use strict;
use Buhindana;
use Buhin;
        my $buhindana = Buhindana->new;
        $buhindana->addBuhin(Buhin->new("CPU"));
        $buhindana->addBuhin(Buhin->new("メモリ"));
        $buhindana->addBuhin(Buhin->new("マザーボード"));
        $buhindana->addBuhin(Buhin->new("ハードディスク"));
        my $it = $buhindana->iterator();
        while ($it->hasNext()) {
            my $buhin = $it->next();
            print $buhin->getName(), "\n";
        }

最後に本コンテンツの元は、結城先生のご著書「デザインパターン入門」を大変参考にしています。いつもありがとうございます。本格的にデザインパターンを勉強するのであれば、絶対に「買い」です!

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

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