Iteratorパターンとは
リストの内部構造を隠したまま、それぞれの要素にアクセスさせるためのAPIを提供するパターンのこと。
GoF本では、以下のように定義されている。
集約オブジェクトが基にある内部表現を公開せずに、その要素に順にアクセスする方法を提供する。
図にするとこんな感じ。
・Iteratorクラス
要素にアクセスするためのAPIを提供する
・ConcreteIteratorクラス
Iteratorで定義されたAPIを実装する。
・Aggregateクラス
Iteratorオブジェクトを返すAPIを提供する
・ConcretaAggregateクラス
リスト固有のIteratorオブジェクトを返す
PHPでIteratorパターン
まずは友達を表すオブジェクト。こいつを走査することになる。
<?php class FriendBean { private $name; private $age; private $job; public function __construct($name, $age, $job) { $this->name = $name; $this->age = $age; $this->job = $job; } public function getName() { return $this->name; } public function getAge() { return $this->age; } public function getJob() { return $this->job; } }
上の友達Beanを配列にして格納するオブジェクト。
IteratorAggregateをimplementsしてる。
<?php require_once 'FriendBean.php'; ?> <?php class Friends implements IteratorAggregate { private $friends; public function __construct() { $this->friends = new ArrayObject(); } public function add(FriendBean $friendBean) { $this->friends[] =$friendBean; } public function getIterator() { return $this->friends->getIterator(); } } ?>
・友達Beanを特定の条件で絞って走査するオブジェクト
<?php require_once 'FriendBean.php'; ?> <?php class ProgrammerIterator extends FilterIterator { public function __construct($iterator) { parent::__construct($iterator); } //FilterIteratorのacceptをovarrideしてる。 //イテレータの現在の要素がフィルタを満たすかどうかを調べる public function accept() { //currentは現在の要素を返す $friend = $this->current(); return ($friend->getJob() === 'PROGRAMMER'); } } ?>
で、上のオブジェクト達を使うclient。
<?php require_once 'FriendBean.php'; require_once 'Friends.php'; require_once 'ProgrammerIterator.php'; ?> <?php $friends = new Friends(); $friends->add(new FriendBean('Mizky', 28, 'PROGRAMMER')); $friends->add(new FriendBean('Yoshida',30, 'POLICEMAN')); $friends->add(new FriendBean('sho322', 28, 'PROGRAMMER')); $friends->add(new FriendBean('Mita', 29, 'ELEKIMEN')); $iterator = $friends->getIterator(); echo '<ul>'; //iterator=>validは現在位置が有効かどうかを調べるメソッド。 //JavaのhasNextみたいなものだと思う。 while ($iterator->valid()) { $friendBean = $iterator->current(); printf('<li>%s (%d, %s)</li>', $friendBean->getName(), $friendBean->getAge(), $friendBean->getJob() ); $iterator->next(); } echo '</ul>'; echo '<hr>'; $iterator->rewind(); $progIterator = new ProgrammerIterator($iterator); foreach ($progIterator as $friendBean) { printf('<li>%s (%d, %s)</li>', $friendBean->getName(), $friendBean->getAge(), $friendBean->getJob() ); } echo '</ul>'; echo '<hr>'; ?>
ブラウザでクライアントを開くと以下のように表示される。
Mizky (28, PROGRAMMER) Yoshida (30, POLICEMAN) sho322 (28, PROGRAMMER) Mita (29, ELEKIMEN) ------------------------ Mizky (28, PROGRAMMER) sho322 (28, PROGRAMMER)
参考文献

- 作者: 下岡秀幸,道端良,畑勝也
- 出版社/メーカー: 秀和システム
- 発売日: 2006/11
- メディア: 大型本
- 購入: 4人 クリック: 39回
- この商品を含むブログ (29件) を見る
PHPを勉強しながらデザインパターンを学ぶことができる非常に貴重な本。
その言語でオブジェクト指向プログラミングを身につけるには、デザインパターンを実装してみるのが一番だと思う。
感謝のプログラミング
今回で感謝のプログラミングは【444時間目】
10000時間まで、あと【9556時間】