GoFのデザインパターンのIteratorパターンを勉強してみます。
Iteratorパターン
集約オブジェクトが基にある内部表現を公開せずに、その要素に順にアクセスする方法を提供する
リストのようなパターンで使用するパターンです。
振る舞いに関するパターンになっています。
パターンのためリストが同じインターフェースになり、リストを使う際には同じ使い方ができるようになると考えられます。
使い方
interface Iterator{ public function First(); public function Next(); public function IsDone(); public function CurrentItem(); } interface Aggregate{ protected function Iterator(); } class ChildListIterator implements Iterator { private $list; private $index; private $count; public function _construct($list){ $this->list= $list; $this->index = 0; $this->count = count($list); } public function First(){ $this->index = 0 } public function Next(){ $this->index++ } public function IsDone(){ return $this->index < $this->count; } public function CurrentItem(){ if( !$this->IsDone() ){ // throw error } return $this->list[$this->index] } } class ChildList implements Aggregate { private $itr; private $list; public function _construct($list){ $this->list = $list; } public function callChildren(){ $itr =$this->iterator(); for($itr->First(); $itr->IsDone(); $itr->Next()){ // 処理 $data = $itr->CurrentItem(); } } protected function Iterator(){ if(empty($this->itr)){ $this->itr = new ChildListIterator($this->list); } return $this->itr; } } class Child { private name = ""; public function getName(){ return $this->name; } }
リストを作るために使用してみましたが、なにがしたいのか実感できない状態になった気がします。
理解しきれていないため曖昧な使い方になりましたが、list部分の操作がinterfaceに定義されて統一されたという感じになりました。
iteratorの内容が複数になればいいのか、aggregateが複数になればいいのか考えましたが、aggregateのconstructにiteratorを渡すことでiteratorを増やすことで拡張性が高い感じがしています。
雑記
GoFのデザインパターンにはありませんが、aggregateパターンもどこかで記事にしたいです。
ドメイン駆動の際にはAggregateパターンが重要になってくるため、しっかりと理解したいです。