PHP デザインパターン(Iteratorパターン)

Iteratorパターン

↓買ったので、JavaPHPに読み替えて勉強。そのためのメモ。

CD(Cdクラス)をCD棚(CdShelfクラス)に入れて、イテレータで取り出してCDの名前を表示する

<?php
class Cd{
	private $name;
	public function __construct($name){
		$this->name = $name;
	}
	public function getName(){
		return $this->name;
	}
}

interface Aggregate{
	function iterator();
}

interface myIterator{
	function hasNext();
	function next();
}

class CdShelf implements Aggregate{
	private $Cds;
	private $last;

	function __construct(){
		$this->Cds = array();
		$this->last = 0;
	}
	function iterator(){
		return new CdShelfIterator($this);
	}
	function appendCd($Cd){
		$this->Cds[$this->last] = $Cd;
		$this->last++;
	}
	function getCd($index){
		return $this->Cds[$index];
	}
	function getLength(){
		return $this->last;
	}
}


class CdShelfIterator implements myIterator{
	private $CdShelf;
	private $index;
	
	function __construct($CdShelf){
		$this->CdShelf = $CdShelf;
		$this->index = 0;
	}
	function hasNext(){
		if($this->index < $this->CdShelf->getLength()){
			return true;
		}else{
			return false;
		}
	}
	function next(){
		$Cd = $this->CdShelf->getCd($this->index);
		$this->index++;
		return $Cd;
	}
}

$CdShelf = new CdShelf;
$CdShelf->appendCd(new Cd("ねぇ"));
$CdShelf->appendCd(new Cd("いきものばかりメンバーズBESTセレクション"));
$CdShelf->appendCd(new Cd("THE BEST BANG!!"));
$CdShelf->appendCd(new Cd("Request"));
$CdShelf->appendCd(new Cd("8UPPERS"));

$CdShelfIterator = $CdShelf->iterator();

while($CdShelfIterator->hasNext()){
	$Cd = $CdShelfIterator->next();
	print $Cd->getName()."<br/>";
}

?>
PHPIteratorを使って同じことをやってみる

<?php
class Cd{
	private $name;
	public function __construct($name){
		$this->name = $name;
	}
	public function getName(){
		return $this->name;
	}
}


interface Aggregate{
	function iterator();
}


class CdShelf implements Aggregate{
	private $Cds;
	private $last;

	function __construct(){
		$this->Cds = array();
		$this->last = 0;
	}
	function iterator(){
		return new CdShelfIterator($this);
	}
	function appendCd($Cd){
		$this->Cds[$this->last] = $Cd;
		$this->last++;
	}
	function getCd($index){
		return $this->Cds[$index];
	}
	function getLength(){
		return $this->last;
	}
}


class CdShelfIterator implements Iterator{
	private $CdShelf;
	private $index;
	
	function __construct($CdShelf){
		$this->CdShelf = $CdShelf;
		$this->index = 0;
	}
	function current(){
		return $this->CdShelf->getCd($this->index);
	}
	function key(){
		return $this->index;
	}
	function next(){
		++$this->index;
	}
	function rewind(){
		$this->index=0;
	}
	function valid(){
		if( $this->index < $this->CdShelf->getLength() ){
			return true;
		}else{
			return false;
		}	
	}

}

$CdShelf = new CdShelf;
$CdShelf->appendCd(new Cd("ねぇ"));
$CdShelf->appendCd(new Cd("いきものばかりメンバーズBESTセレクション"));
$CdShelf->appendCd(new Cd("THE BEST BANG!!"));
$CdShelf->appendCd(new Cd("Request"));
$CdShelf->appendCd(new Cd("8UPPERS"));

$CdShelfIterator = $CdShelf->iterator();

while($CdShelfIterator->valid()){
	$Cd = $CdShelfIterator->current();
	print $Cd->getName()."<br/>";
	$CdShelfIterator->next();
}

?>

Iteratorを使うとうれしいこと

CDの取り出し(whileループ部分)が、CD棚(CdShelfクラス)の実装と切り離せる。
つまり
CD棚の仕組みを変更したとしても正しいIteratorを返せば、CDの取り出し作業は同じやり方でよくなる。