@blog.justoneplanet.info

日々勉強

PHPでデザインパターン:Iterator(イテレータ)

■コード

Student.php

class Student
{
    private $name;
    private $age;
    private $gender;
    public function __construct($name, $age, $gender)
    {
        $this->name   = $name;
        $this->age    = $age;
        $this->gender = $gender;
    }
    public function getName()
    {
        return $this->name;
    }
    public function getAge()
    {
        return $this->age;
    }
    public function getGender()
    {
        return $this->gender;
    }
}

Students.php

class Students implements IteratorAggregate
{
    private $students;
    public function __construct()
    {
        $this->students = new ArrayObject();// ArrayObjectで配列オブジェクトとして内部で保持
    }
    public function add(Student $student)
    {
        $this->students[] = $student;
    }
    public function getIterator()
    {
        return $this->students->getIterator();// 配列オブジェクトのイテレータ
    }
}

MaleIterator.php

FilterIteratorを用いることで以下のようにiteratorに付加的な機能を提供できる。

require_once 'Student.php';

class MaleIterator extends FilterIterator
{
    public function __construct($iterator)
    {
        parent::__construct($iterator);
    }
    public function accept()
    {
        $student = $this->current();
        return ($student->getGender() === 'male');
    }
}

■クライアントコード

require_once 'Student.php';
require_once 'Students.php';
require_once 'MaleIterator.php';

$students = new Students();
$students->add(new Student('John', 12, 'male'));
$students->add(new Student('Jack', 13, 'male'));
$students->add(new Student('Emily', 14, 'female'));

$iterator = $students->getIterator();
while($iterator->valid()){
    $student = $iterator->current();
    $list[] = array(
        'name'   => $student->getName(),
        'age'    => $student->getAge(),
        'gender' => $student->getGender()
    );
    $student = $iterator->next();
}
var_dump($list);
/*
array(3) {
  [0]=>
  array(3) {
    ["name"]=>
    string(4) "John"
    ["age"]=>
    int(12)
    ["gender"]=>
    string(4) "male"
  }
  [1]=>
  array(3) {
    ["name"]=>
    string(4) "Jack"
    ["age"]=>
    int(13)
    ["gender"]=>
    string(4) "male"
  }
  [2]=>
  array(3) {
    ["name"]=>
    string(5) "Emily"
    ["age"]=>
    int(14)
    ["gender"]=>
    string(6) "female"
  }
}
*/
$iterator = new MaleIterator($iterator);
foreach($iterator as $student){
    $list[] = array(
        'name'   => $student->getName(),
        'age'    => $student->getAge(),
        'gender' => $student->getGender()
    );
}
var_dump($list);
/*
array(2) {
  [0]=>
  array(3) {
    ["name"]=>
    string(4) "John"
    ["age"]=>
    int(12)
    ["gender"]=>
    string(4) "male"
  }
  [1]=>
  array(3) {
    ["name"]=>
    string(4) "Jack"
    ["age"]=>
    int(13)
    ["gender"]=>
    string(4) "male"
  }
}
*/

きれいだ。

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment