なんかやるBLOG Written by hikaru

デザインパターン IteratorをPython3で理解する

プログラミング

この記事を読むとGoFのデザインパターンの一つであるIteratorを完全にざっくり大体理解できる。

Iteratorパターンとは?

「集合体(Aggregation)」に対して、下記2つの機能を提供するデザインパターン。
1. 要素の取得時に集合体自身をカプセル化する
2. 集合体から要素を取得する方法を抽象化する

classDiagram List -- ListIterator : creates Client -- ListIterator : uses class List{ +__iter__() ListIterator } class ListIterator{ +__iter__() +__next__() } class Client{ -listIterator ListIterator +operation() }

上図の場合、PythonのList classが「集合体(Aggregation)」にあたる。
forステートメントなどで順番に要素を取得する処理を行う際、List classはListIteratorというclassを生成する。
このclassは反復子(Iterator)と呼ばれ、__next__()という組み込みメソッドを持つ。
反復子は呼び出し元のListの属性、現在のindexの情報を保持しており、__next__()が実行されると現在のindexの要素が呼ばれ、自身のindexをインクリメントする。__next__()が実行されるたびに順番に次の要素が呼ばれていき、最後にStopIterationの例外を送出する。

先に述べたIteratorパターンの機能の1つ目、集合体自身のカプセル化はIteratorオブジェクトが参照されることにより集合体自身に対するアクセス・変更をブロックすることで達成される。
2つ目の機能である取得方法の抽象化は、__next__()メソッドにより達成される。利用者自身は具体的な取得処理を考える必要はなく、__next__()を実行すれば次の要素が得られる。

Listのイテレータは単純に追加した順番で要素を返すが、たとえばランダム取得を行うイテレータが欲しければ__next__()と__iter__()を定義したオリジナルのイテレータを作ることも可能。

あんまり分かりやすく書けなかった気もするが

オワリ