Bookmark and Share

Lee's 程序人生

HTML CSS Javascript XML AJAX ATLAS C# C++ 数据结构 软件工程 设计模式 asp.net Java 数字图象处理 Sql 数据库
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

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 虚拟类 : 

 

require_once 'Zend/Feed/Element.php';

/**
 * 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 

我要啦免费统计