東京のWeb制作会社LIGLIGならできるおもしろいこと。Iteratorパターン王2015.02.10Web制作シェアこんにちは、エンジニアの王です。今回は、Iteratorパターンをご紹介したいと思います。「iterate」は「◯◯を繰り返す」という意味で、プログラミングにおいてはもっぱら「for」や「while」などを用いた「反復処理」をするという意味で使われます。パターン」は、集約オブジェクト(コレクションオブジェクト)の中の要素を列挙する手段を提供して、具体的な列挙方法を集約オブジェクトから隠蔽することで、列挙方法を抽象化します。なんだか難しいように思えますが、心配することはありません。後ほど実際にコードを見れば、すぐに分かると思います。パターン集約オブジェクトって?何らかの「情報の集まり」を格納したオブジェクトのことです。「配列」が最も単純な集約オブジェクトでしょう。];集約オブジェクトをiterateするただの配列ですので、foreachで回すだけです。上記ではごくごく単純な配列の列挙ですから、foreachなどで回して何らかの処理をする分には、特に問題は感じなかったでしょう。現場ではこんな単純なケースは少ないと思います。複雑なケースでは、Iteratorパターンを検討しましょう。例で「書籍」クラスを考えてみましょう。例:「書籍」クラス先ほどの$name_listを書籍クラスの中の「執筆者一覧」だと仮定しましょう。後日集約オブジェクトの$name_listの中身が変わって、下記になったとします。'Ryu',],];データの構造が変わったので、同じ出力をするためには以前に書いたコードを書き直しますよね。3],];さあ、またまた改修作業が必要です。これが一箇所で使われているのならまだしも、10箇所、20箇所で使っていたら全て置き換えるのは大変です。なったら、たいていの人はこの処理を関数化・メソッド化しようと考えだすでしょう。集約オブジェクトの個々の要素のデータ構造が変わったり、ソート方法が変わったりなどといったとき、以前に書いたコードを変える必要が出てきてしまいます(OCPを違反する)。異なる集約オブジェクトを処理する際にクラス内で判定処理を挟んで、「このタイプであればこう、あのタイプであればこう」といった具合にタイプ別で列挙処理をすることで、クラスの柔軟性が損なわれてしまいます。集約オブジェクトに「iteratorオブジェクト」を提供させることであっさり解決します。「iteratorオブジェクト」は集約オブジェクトを列挙する方法を知っているので、クライアント(iteratorを使うオブジェクト)は実装の詳細を知る必要はなく、「iteratorオブジェクト」の使い方さえ知っていればいいです。すれば、後からいくら集約オブジェクトのタイプが増えても、クライアント側の記述そのままで大丈夫になりますので、プログラムの柔軟性がぐっと上がります。Iteratorクラス、このクラス内で列挙の手順を記述する。AuthorIteratorインターフェイスを実装するようにする。クラス間で共有しているメソッドたちを分離しておく。今回の場合、AuthorListがAggregate、AuthorIteratorがIteratorインターフェイスに当たりますよね。AggregateがIteratorを返して、Iteratorの内部で要素を列挙するといった構造になっています。パターン」を使って、コレクション内の要素を列挙する仕事をIteratorに任せっきりにして、列挙する具体的な手順を抽象化することで、プログラムの拡張性や柔軟性が向上したことがコードを読んでおわかりいただけたかと思います。インターフェイスがあって、このインターフェイスを実装することで、コレクションをforeachで回せるようになります。Iteratorの概念そのものは同じです。本記事で言及している古典的なIteratorに比べて実装する必要があるメソッドは“5個”と、ちょいと多い感じです。POSTLIGへの自由なメッセージお待ちしています頂いたご意見への回答は行っておりません。