感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

PHPでIteratorパターン。

スポンサーリンク

Iteratorパターンとは

リストの内部構造を隠したまま、それぞれの要素にアクセスさせるためのAPIを提供するパターンのこと。

GoF本では、以下のように定義されている。

集約オブジェクトが基にある内部表現を公開せずに、その要素に順にアクセスする方法を提供する。

図にするとこんな感じ。

Iteratorクラス
要素にアクセスするためのAPIを提供する

・ConcreteIteratorクラス
Iteratorで定義されたAPIを実装する。

・Aggregateクラス
Iteratorオブジェクトを返すAPIを提供する

・ConcretaAggregateクラス
リスト固有のIteratorオブジェクトを返す

PHPIteratorパターン

まずは友達を表すオブジェクト。こいつを走査することになる。

<?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)

参考文献

PHPによるデザインパターン入門

PHPによるデザインパターン入門


PHPを勉強しながらデザインパターンを学ぶことができる非常に貴重な本。
その言語でオブジェクト指向プログラミングを身につけるには、デザインパターンを実装してみるのが一番だと思う。

感謝のプログラミング

今回で感謝のプログラミングは【444時間目】
10000時間まで、あと【9556時間】