デザインパターン学習メモ:「Iterator」


目的

GoF本より引用する。

集約オブジェクトが基にある内部表現を公開せずに、その要素を順にアクセスする方法を提供する。(P.275)

翻訳がやや明快ではないので、原書からも引用する。

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.(P.257)

Iteratorパターンを用いることで、集約オブジェクトの内部実装と走査方法が切り離される。これによって、走査方法の変更が容易になる。

また、異なる集約オブジェクト間で共通の走査方法を提供することができる。

実装例

『デザインパターン入門』を参考に作成した。

Aggregate.java
// Aggregate役
// 集約オブジェクトが実装する(走査するためのIteratorを提供する)
public interface Aggregate {
    // Iteratorを生成
    public Iterator<Item> createIterator();
}
Iterator.java
// java.utilに含まれるクラス
// 今回の例に必要な箇所を抜粋
public interface Iterator<E> {
    boolean hasNext(); 
    E next();
    ...
}
Tray.java
// ConcreteAggregate役
// 具体的な集約オブジェクト
public class Tray implements Aggregate {
    private static final int MAX_SIZE = 100;
    private Item[] items = new Item[MAX_SIZE];
    private int last = 0;

    public Tray() {
    }

    public int getSize() {
        return last;
    }

    public Item getAt(int index) {
        return items[index];
    }

    public void addItem(Item item) {
        this.items[last] = item;
        last++;
    }

    @Override
    public Iterator<Item> createIterator() {
        return new TrayIterator(this);
    }
}
TrayIterator.java
// ConcreteIterator役
// 具体的なIterator
public class TrayIterator implements Iterator<Item> {
    private Tray tray;
    private int index;

    public TrayIterator(Tray tray) {
        this.tray = tray;
        this.index = 0;
    }

    @Override
    public boolean hasNext() {
        if (index < tray.getSize()) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Item next() {
        Item item = tray.getAt(index);
        index++;
        return item;
    }
}

実行例

Main.java
public class Main {
    public static void main(String[] args) {
        Tray tray = new Tray();
        tray.addItem(new Item("item-A"));
        tray.addItem(new Item("item-B"));
        tray.addItem(new Item("item-C"));

        Iterator<Item> iterator = tray.createIterator();
        while (iterator.hasNext()) {
            Item item = iterator.next();
            System.out.println(item.getName());
        }
    }
}
結果
item-A
item-B
item-C

参考文献

  • エリック ガンマ、ラルフ ジョンソン、リチャード ヘルム、ジョン プリシディース(1999)『オブジェクト指向における再利用のためのデザインパターン 改訂版』本位田 真一、吉田 和樹 監訳、SBクリエイティブ
  • 結城浩(2004)『Java言語で学ぶ デザインパターン入門』SBクリエイティブ