
絶版されているけれど、Google booksで公開されているのが見れます。
https://books.google.co.jp/books?id=sXNh4TeQeBIC&printsec=frontcover&hl=ja#v=onepage&q&f=false
1日1パターンってことで演習してアウトプットしていきます。
iterate = 反復する、繰り返す。
Iteratorパターンはオブジェクトに対する反復操作を行うための統一APIを提供するパターン。
Iteratorパターンはオブジェクトのふるまいに注目したパターンで、利用者にリストの内部構造を隠したまま、それぞれの要素にアクセスさせるためのAPIを提供することを目的としている。
もくじ
使いどころ
- 配列が入るが、どういう配列構造かはわからない。
実装のポイント
Iteratorパターンのメリット
非カプセル化を行うパターン。
集約オブジェクトに対する操作を別クラスとして切り出して、オブジェクトが不要に肥大化したり複雑になることを避ける。切り出されたクラスを切り替えることで様々な操作をサポートできるようする。
Employees.class.php
<?php
require_once 'Employee.class.php';
// SPL(Standard PHP Library)
// ArrayObjectクラス
// 配列をオブジェクトとして扱うためのラッパークラス
// ArrayIteratorクラス
// 配列用のiteratorクラス。ConcreteIteeratorクラスに相当する
// FilterIteratorクラス
// iterator用のフィルタクラス。また中小クラスとして定義されているため、
// 利用するにはクラスの継承を行い、acceptメソッドを実装する必要がある
// IteratorAggregateクラス
// Aggregateクラスに相当する。
// Iteratorを生成する為のメソッドgetIteratorが宣言されている
class Employees implements IteratorAggregate {
private $employees;
public function __construct()
{
$this->employees = new ArrayObject();
}
public function add(Employee $employee)
{
$this->employees[] = $employee;
}
public function getIterator()
{
return $this->employees->getIterator();
}
}
Employees.class.php
<?php
require_once 'Employee.class.php';
// SPL(Standard PHP Library)
// ArrayObjectクラス
// 配列をオブジェクトとして扱うためのラッパークラス
// ArrayIteratorクラス
// 配列用のiteratorクラス。ConcreteIteeratorクラスに相当する
// FilterIteratorクラス
// iterator用のフィルタクラス。また中小クラスとして定義されているため、
// 利用するにはクラスの継承を行い、acceptメソッドを実装する必要がある
// IteratorAggregateクラス
// Aggregateクラスに相当する。
// Iteratorを生成する為のメソッドgetIteratorが宣言されている
class Employees implements IteratorAggregate {
private $employees;
public function __construct()
{
$this->employees = new ArrayObject();
}
public function add(Employee $employee)
{
$this->employees[] = $employee;
}
public function getIterator()
{
return $this->employees->getIterator();
}
}
SalesmanIterator.class.php
<?php
require_once 'Employee.class.php';
// FilterIterator
// オブジェクトを包み込むクラス
class SalesmanIterator extends FilterIterator {
public function __construct($iterator) {
parent::__construct($iterator);
}
// ArrayIteratorオブジェクトに「動作を変更する」という機能を提供する為に、
// accetpt()メソッドに取得する条件を実装する
public function accept() {
$employee = $this->current();
return ( $employee->getJob() === 'SALESMAN' );
}
}
iterator_client.php
<?php
require_once 'Employee.class.php';
require_once 'Employees.class.php';
require_once 'SalesmanIterator.class.php';
?>
<?php
function dumpWithForeach($iterator) {
echo '<ul>';
foreach ($iterator as $employee) {
printf('<li>%s (%d, %s)</li>',
$employee->getName(),
$employee->getAge(),
$employee->getJob());
}
echo '</ul>';
echo '<hr>';
}
?>
<?php
$employees = new Employees();
$employees->add( new Employee('SMITH', 32, 'CLERK') );
$employees->add( new Employee('ALLEN', 26, 'SALESMAN') );
$employees->add( new Employee('MARTIN', 50, 'SALESMAN') );
$employees->add( new Employee('KATO', 44, 'MANAGER') );
$iterator = $employees->getIterator();
/**
* iteratorメソッドを利用する
**/
echo '<ul>';
while ($iterator->valid()) {
$empoyee = $iterator->current();
printf('<li>%s (%d, %s)</li>',
$empoyee->getName(),
$empoyee->getAge(),
$empoyee->getJob());
$iterator->next();
}
echo '</ul>';
echo '<hr>';
/**
* foreachを利用する
**/
dumpWithForeach($iterator);
/**
* 異なるiteratorで要素を取得する
**/
dumpWithForeach(new SalesmanIterator($iterator));
DEMO
/demo/Design-Pattern-Primer-by-PHP/Iterator/iterator_client.php
@see

