Iteratorパターン

2020/10/23 23:46

GoFのIteratorパターンについて動画でわかりやすく解説しています。オブジェクトを集約する複数の構造について、統一した要素の取り出し処理を用意して、使い手側が集約構造を意識せずに順番に値を取り出せるようにする仕組みです。概念とコードを含めて10分の動画です。テキストの解説でJavaScriptやJavaでの利用のされ方を例示しています。

Iteratorパターンとは

配列のような複数のオブジェクトを集約する構造のオブジェクト(Aggregate Interface)が、その実装の詳細を隠した上で内部の要素に順番にアクセスする方法( Iterator Interface )を提供します。集約しているオブジェクトの実装の差異をうまく吸収して、統一的なアクセスを実現するための方法として利用できるでしょう。

ただ、現在ではIteratorを自分の手で実装するというケースはかなり少なくなっていると思われます。ライブラリの実装にこの考え方が生かされているようなケースは多いのではないでしょうか。

Iteratorの例

JavaScriptの「for ... of」

例えば、JavaScriptの繰り返しの仕様である「for ... of」 の場合、例として様々なオブジェクトを繰り返して値が取得できる事が示されています。配列や文字列、DOMコレクションなど、それぞれ特に関係が無さそうなオブジェクトが皆「for ... of」で繰り返せるように抽象化されています(参考: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...of )。

その実装には Iterableプロトコル( https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Iteration_protocols#iterable )という繰り返しの為の仕様を実装してさえいれば、「for ... of」で利用できると示されています(ここで言うプロトコルはインターフェースとその実装のルール思うとイメージが掴めるかもしれません)。

JavaのArrayListやLinkedList

JavaではArrayList(ランダムアクセスできる配列に近い構造)、LinkedList(連結リスト構造)のように複数の実装を適用したコレクションクラスがあります。アルゴリズムとデータ構造について学習するとわかりますが、これらのコレクションはそれぞれに性能の特性があって、それに合わせた取り出し方をする必要があります。

例えばランダムアクセスが速いArrayListならインデクス番号を渡せば瞬時に内部のオブジェクトを取り出す事ができますが、LinkedListではインデクスを渡されると先頭から順番にオブジェクトを数えないといけないために、データの数が増えると取り出しが大変遅くなってしまいます。

Iteratorインターフェースを提供する事で、どちらのコレクションでも使い手側からは同じ取り出し方でなるべく速度は維持しながら順番に内部のオブジェクトを取り出せるように設計されています。

この記事を書いた人

佐藤 正志

サークルアラウンド株式会社 代表取締役