?迭代器(Iterator)模式,又叫做游標(Cursor)模式。GOF給出的定義為:提供一種方法訪問一個容器(container)對象中各個元素,而又不需暴露該對象的內部細節。
百度百科:?http://baike.baidu.com/view/9791023.htm?fr=aladdin
解釋
上面這名話可能多數人看得似懂非懂,什么叫做訪問容器的各個元素,又不暴露對象的內部細節呢?尤其是網上很多例子都過于簡單,直接扔一個數組,然后去實現了迭代器的各種方法,如下:
?<?php
class SomeCollection implements Iterator
{
protected $_data;
protected $_pos;
?
function __construct($data)
{
$this->_data = $data;
$this->_pos = 0;
}
?
function current()
{
$row = $this->_data[$this->_pos];
return $row;
}
?
function next()
{
$this->_pos++;
}
?
function valid()
{
return $this->_pos >= 0 && $this->_pos <count($this->_data);
}
?
function key()
{
return $this->_pos;
}
?
function rewind()
{
$this->_pos = 0;
}
}
?
$array = array(
array('url' => 'www.zeroplace.cn'),
array('url' => 'www.baidu.com'),
array('url' => 'www.sina.com.cn'),
array('url' => 'www.google.com'),
array('url' => 'www.qq.com'),
);
?
$coll = new SomeCollection($array);
?
foreach ($coll as $row) {
echo $row['url'], "\n";
}
這樣的例子就不能夠說明迭代器的作用,因為它不能說明迭代器隱藏了內部的數據結構,傳進去的和返回出來的完全是一樣的數據。
迭代器怎么用
我只能說在不同的場合有不同的用法。比如我把上面的例子修改一下,可能就可以說明迭代器可以隱藏數據結構這個特性了。請看如下代碼。
?<?php
class SomeCollection implements Iterator
{
protected $_data;
protected $_pos;
?
function __construct($data)
{
$this->_data = $data;
$this->_pos = 0;
}
?
function current()
{
$row = $this->_data[$this->_pos];
$row['ip'] = gethostbyname($row['url']);
return $row;
}
?
function next()
{
$this->_pos++;
}
?
function valid()
{
return $this->_pos >= 0 && $this->_pos <count($this->_data);
}
?
function key()
{
return $this->_pos;
}
?
function rewind()
{
$this->_pos = 0;
}
}
?
$array = array(
array('url' => 'www.zeroplace.cn'),
array('url' => 'www.baidu.com'),
array('url' => 'www.sina.com.cn'),
array('url' => 'www.google.com'),
array('url' => 'www.qq.com'),
);
?
$coll = new SomeCollection($array);
?
foreach ($coll as $row) {
echo $row['url'], ' ', ?$row['ip'], "\n";
}
這樣我覺得就可以說明迭代器能隱藏數據結構這個特性了。我們的數據傳進去的時候每行數據只有一個url屬性,但是迭代出來的時候多了一個ip屬性。這樣對外部的使用者來說就是有兩個屬性(url和ip), 它不需要知道這個ip字段是創建者傳入的還是在迭代器中產生的。
更一般的做法
這里current方法返回的是一個關聯數組,更常規的做法是返回一個對象,此時這個迭代器可能還需要一個對象創建器。