Iterator Pattern
- Date
- 2006-07-16 (Sun)
- Category
- Design Pattern | php
もう今更ですが、PHP 再入門というか、Object 指向再入門してみようと思い立ちました。だいぶ前に買って一度 java でやったのですが、PHP でやってやろうと。
目次通りにやって行くつもりなので、初回はやや簡単ですが、Iterator です。
最初にちょっとだけ詰まったのが、関数の戻り値をどうやって参照で渡す方法でした。もちろん本書では Java でやってるので、値を渡す時は参照が基本だけれども、PHP はそうではないので明示してやる必要があります。マニュアル以下のページに書いてあります。
簡単にまとめると
- 変数への参照での代入
$copy =& $originalObject
- 関数の引数を参照で渡すことを明示
function foo(&$var) { $var++; } - 関数の戻り値を参照で返すことを明示
function &foo( $param ) { /* ... コード ... */ return $bar; }
でした。
あと Iterator.php のコード中にでてくるインターフェイス名が YIterator となっているのは、PHP が内部的に Iterator というクラスを定義しているからです。マニュアルを見て発見したですが、CXLV. Standard PHP Library (SPL) 関数 というクラスライブラリが提供されているのですね…スゴいそろってるじゃん。。
SPL-StandardPHPLibrary Class List
foreach を使った時に、iterate されないクラスメンバとかはこれらを使うと設定できるみたいでした。今回のデザインパターン入門が終わったら見てみたいと思います。
以下が本文登場順のコード。
Aggregate.php
<?php
interface Aggregate
{
public function iterator();
}
?>
Iterator.php
<?php
interface YIterator
{
public function hasNext();
public function & next();
}
?>
Book.php
<?php
class Book
{
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
?>
Bookshelf.php
<?php
class BookShelf implements Aggregate
{
private $books;
public function __construct() {
$this->books = array();
}
public function & getBookAt( $index ) {
return $this->books[$index];
}
public function appendBook( &$book ) {
array_push($this->books, $book);
}
public function getLength() {
return count($this->books);
}
public function iterator() {
return new BookShelfIterator($this);
}
}
?>
BookShelfIterator.php
<?php
class BookShelfIterator implements YIterator
{
private $bookshelf;
private $index;
public function __construct( &$bookshelf ) {
$this->bookshelf = $bookshelf;
$this->index = 0;
}
public function hasNext() {
if ($this->index < $this->bookshelf->getLength()) {
return true;
} else {
return false;
}
}
public function & next() {
$book = $this->bookshelf->getBookAt($this->index);
$this->index++;
return $book;
}
}
?>
main.php
<?php
require_once('Aggregate.php');
require_once('Iterator.php');
require_once('Book.php');
require_once('BookShelf.php');
require_once('BookShelfIterator.php');
$bookshelf = new BookShelf();
$bookshelf->appendBook( new Book('Around the World in 80 Days') );
$bookshelf->appendBook( new Book('Bible') );
$bookshelf->appendBook( new Book('Cinderella') );
$bookshelf->appendBook( new Book('Daddy-Long-Legs') );
$it = $bookshelf->iterator();
while($it->hasNext()) {
$book = $it->next();
echo $book->getName()."\n";
}
?>
実行するにはファイルを同じディレクトリに保存して、php main.php としてください。以下が実行結果。
$ php main.php
Around the World in 80 Days
Bible
Cinderella
Daddy-Long-Legs
Comment:0
Trackback:0
- TrackBack URL for this entry
- http://blogs.grf-design.com/mt/mt-tb.cgi/179
- Listed below are links to weblogs that reference
- Iterator Pattern from The Croton