デザインパターン ~Iterator~


1. はじめに

GoFのデザインパターンにおける、Iteratorパターンについてまとめます。

2. Iteratorパターンとは

  • Iterateという英単語は、何かを繰返すという意味になります。
  • Iteratorパターンは、集合体の要素に対し、順番にアクセスする処理を行うための方式です。
  • GoFのデザインパターンでは、振る舞いに関するデザインパターンに分類されます。

3. サンプルクラス図

4. サンプルプログラム

クラス(教室)に生徒を入れ、生徒の名前を順番に表示するプログラムです。

4-1. Iteratorインターフェース

要素を順番にスキャンしていくインターフェースです。

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

4-2. Aggregateインターフェース

Iteratorを作り出すインターフェースです。サンプルでは「集合体」としています。

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

4-3. Studentクラス

集合体の要素となるクラスです。サンプルでは「生徒」としています。

Student.java
public class Student {

    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

4-4. ClassRoomクラス

Aggregateが定めたインターフェースを実装するクラスです。サンプルでは「教室」としています。

ClassRoom.java
public class ClassRoom implements Aggregate {

    private Student[] students;
    private int last = 0;

    public ClassRoom(int maxsize) {
        this.students = new Student[maxsize];
    }

    public Student getStudentAt(int index) {
        return students[index];
    }

    public void appendStudent(Student student) {
        this.students[last] = student;
        last++;
    }

    public int getLength() {
        return last;
    }

    public Iterator iterator() {
        return new ClassRoomIterator(this);
    }
}

4-5. ClassRoomIteratorクラス

Iteratorが定めたインターフェースを実装するクラスです。

ClassRoomIterator.java
public class ClassRoomIterator implements Iterator {

    private ClassRoom classRoom;
    private int index;

    public ClassRoomIterator(ClassRoom classRoom) {
        this.classRoom = classRoom;
        this.index = 0;
    }

    public boolean hasNext() {
        if (index < classRoom.getLength()) {
            return true;
        } else {
            return false;
        }
    }

    public Object next() {
        Student student = classRoom.getStudentAt(index);
        index++;
        return student;
    }
}

4-6. Mainクラス

メイン処理を行うクラスです。

Main.java
public class Main {
    public static void main(String[] args) {

        ClassRoom classRoom = new ClassRoom(4);
        classRoom.appendStudent(new Student("田中"));
        classRoom.appendStudent(new Student("山田"));
        classRoom.appendStudent(new Student("鈴木"));
        classRoom.appendStudent(new Student("佐藤"));

        Iterator iterator= classRoom.iterator();

        while (iterator.hasNext()) {
            Student student = (Student)iterator.next();
            System.out.println(student.getName());
        }
    }
}

4-7. 実行結果

田中
山田
鈴木
佐藤

5. メリット

Iteratorパターンのメリットとしては、実装とは切り離して、数え上げを行うことができることにあります。
デザインパターンはクラスを部品として使えるようにし、再利用性を促進するものなのです。
サンプルプログラムのMainクラスで使われているIteratorメソッドは、hasNext()、next()のみになります。つまり、ClassRoomクラスに依存しない実装となっており、配列のサイズ等を気にしなくてよくなります。

6. GitHub

7. デザインパターン一覧

8. 参考

今回の記事、及びサンプルプログラムは、以下の書籍を元に作成させて頂きました。

大変分かりやすく、勉強になりました。感謝申し上げます。
デザインパターンやサンプルプログラムについての説明が詳細に書かれていますので、是非書籍の方もご覧ください。