【Gang of Four】デザインパターン学習 - Iterator


Iterator - イテレータ

目次
モダンな言語を使用していれば、わざわざ実装することのなさそうなパターンです。

がしかし、標準ライブラリにそのようなモジュールがなかった時代に、先人達が歩んできた足跡をなぞるつもり?で実装してみます。

目的

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

(Listのことをしっかり定義するとこんな表現になるんですね...)

構成要素

・Iterator 要素に順番にアクセスしたりするための抽象クラス
・ConcreteIterator Iteratorクラスの具象クラス
・Aggregate Iterator型のインスタンスを生成するための抽象クラス
・ConcreteAggregate Aggregateクラスの具象クラス

実装

JavaのIterator的なものを実装してみます。
AggregateConcreteAggregateはどんな実装をしていつ使うがやろう。
ジェネリクス型でIteratorを実装すれば不要だと考える。

Iterator 要素に順番にアクセスしたりするための抽象クラス

Iterator.kt
package iterator

interface Iterator<T> {
    var index: Int
    var list: ArrayList<T>

    /**
     * index番目の要素を取得する
     */
    fun elementAt(index: Int): T

    /**
     * まだ要素が残っているかを確認する
     */
    fun hasNext(): Boolean

    /**
     * 次の要素を取得する
     */
    fun next(): T

    /**
     * 要素を追加する
     */
    fun add(element: T)

    /**
     * index番目の要素を削除する
     */
    fun remove(index: Int)
}

ConcreteIterator Iteratorクラスの具象クラス

ConcreteIterator.kt
package iterator

class ConcreteIterator<T>(vararg elements: T): Iterator<T> {

    override var index = 0
    override var list = ArrayList<T>()

    init {
        list.addAll(elements)
    }

    override fun elementAt(index: Int): T {
        return list[index]
    }

    override fun hasNext(): Boolean {
        return index != list.size
    }

    override fun next(): T {
        return list[index++]
    }

    override fun add(element: T) {
        list.add(element)
    }

    override fun remove(index: Int) {
        list.removeAt(index)
    }
}s

使う人

Client.kt
package iterator

class Client {
    init {
        val strIterator = makeStrIterator()
        while(strIterator.hasNext()) {
            println(strIterator.next())
        }

        val intIterator = makeIntIterator()
        while (intIterator.hasNext()) {
            println(intIterator.next())
        }
    }

    private fun makeStrIterator(): Iterator<String> {
        val iterator = ConcreteIterator("いち", "に", "さん")
        iterator.add("よん")

        return iterator
    }

    private fun makeIntIterator(): Iterator<Int> {
        return ConcreteIterator(1, 2, 3)
    }
}

出力結果

[out-put]
いち
に
さん
よん
1
2
3

以上で、先人の苦労を知ることができました。