Zend Framework 与设计模式 (五) - iterator 迭代子模式
Posted on 2010-02-05 19:52 analyzer 阅读(420) 评论(0) 编辑 收藏 举报Iterator 迭代子模式提供了一种访问集合的公共机制。它能够让你以同样的方式遍历,访问和操作数据集合,如数组,文件夹,RSS集合,数据库数据集等等。
Php5 其中一个与 Php4 不同的地方就在于它封装了各种 iterator 接口,这使得在 Php5 中实现 iterator 迭代子变得非常容易。
在 Zend Framework 中也大量使用了 iterator 类接口。下面我将以 Zend_Feed 为例,看看它是如何实现 iterator 迭代子的 :
以下源代码经过简化,首先是 Zend_Feed_Element :
* Zend_Feed_Element 用于封装 DOMElement
*/
class Zend_Feed_Element implements ArrayAccess
{
// @var DOMElement DOM 对象
protected $_element;
// Zend_Feed_Element 构建函数.
public function __construct($element = null)
{
$this->_element = $element;
}
// ......
/**
* ArrayAccess 接口函数
* 判断元素属性是否存在
*/
public function offsetExists($offset)
{
// ......
return $this->_element->hasAttribute($offset);
}
/**
* ArrayAccess 接口函数
* 返回元素属性
*/
public function offsetGet($offset)
{
// ......
return $this->_element->getAttribute($offset);
}
/**
* ArrayAccess 接口函数
* 设置指定的元素属性值
*/
public function offsetSet($offset, $value)
{
// ......
return $this->_element->setAttribute($offset, $value);
}
/**
* ArrayAccess 接口函数
* 重置指定的元素属性值
*/
public function offsetUnset($offset)
{
// ......
return $this->_element->removeAttribute($offset);
}
// ......
}
注意,Zend_Feed_Element 实现了 ArrayAccess 接口,这意味着 Zend_Feed_Element 及其派生类都能以数组的形式被访问。
接下来是 Zend_Feed_Abstract 虚拟类 :
/**
* Zend_Feed_Abstract 类是用于实现 feeds 的虚拟类
* 它实现了两个 PHP5 的核心接口 : ArrayAccess 和 Iterator
*/
abstract class Zend_Feed_Abstract extends Zend_Feed_Element implements Iterator
{
/**
* 当前数据集合索引
* 用于 iterator 实现
* @var integer
*/
protected $_entryIndex = 0;
/**
* 数据集
* @var array
*/
protected $_entries;
// ......
// Iterator 接口函数,重置索引位置
public function rewind()
{
$this->_entryIndex = 0;
}
// Iterator 接口函数,返回当前记录
public function current()
{
return new $this->_entryClassName(
null,
$this->_entries[$this->_entryIndex]);
}
// Iterator 接口函数,返回当前记录的索引
public function key()
{
return $this->_entryIndex;
}
// Iterator 接口函数,索引位置下移
public function next()
{
++$this->_entryIndex;
}
// Iterator 接口函数,当前索引是否正确
public function valid()
{
return 0 <= $this->_entryIndex && $this->_entryIndex < $this->count();
}
// ......
}
Zend_Feed_Abstract 实现了 ArrayAccess 以及 Iterator 接口,这使得我们可以像访问数组一样来访问所有继承自Zend_Feed_Abstract 的数据集。
最后是两个派生类 Zend_Feed_Rss 及 Zend_Feed_Atom 的实例 :
require_once 'Zend/Feed/Abstract.php'; class Zend_Feed_Rss extends Zend_Feed_Abstract { // ...... } class Zend_Feed_Atom extends Zend_Feed_Abstract { // ...... }
事例代码 :
$channel = new Zend_Feed_Rss('http://rss.example.com/channelName'); foreach ($channel as $item) { echo 'Title: ' . $item->title() . "n"; } $feed = new Zend_Feed_Atom('http://atom.example.com/feed/'); foreach ($feed as $entry) { echo 'Title: ' . $entry->title() . "n"; }
Iterator 为应用程序访问数据集合提供了统一的方法,它把操作数据集合的概念抽象出来,使得数据操作对于用户来说达到了真正的透明,同时使用户能够更专注于业务逻辑,在很大程度上提高了开发效率。
转自:http://kbs.kimbs.cn/blog/list/post/17/title/iterator-pattern-in-Zend-Framework