找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 436|回复: 0
打印 上一主题 下一主题

PHP设计模式之迭代器模式的深入解析

[复制链接]

2536

主题

2536

帖子

7532

积分

论坛元老

Rank: 8Rank: 8

积分
7532
跳转到指定楼层
楼主
发表于 2018-2-14 08:20:33 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

            迭代器(Iterator)模式,它在一个很常见的过程上提供了一个抽象:位于对象图不明部分的一组对象(或标量)集合上的迭代。迭代有几种不同的具体执行方法:在数组属性,集合对象,数组,甚至一个查询结果集之上迭代。
在对象的世界里,迭代器模式要维持类似数组的功能,看作是一个非侵入性对象刻面(facet),Client类往往分离自真实对象实现,指iterator接口。只要有可能,我们可以给迭代器传送一个引用,代替将来可能发生变化的具体或抽象类。

参与者:
◆客户端(Client):
引用迭代器模式的方法在一组值或对象上执行一个循环。
◆迭代器(Iterator):在迭代过程上的抽象,包括next(),isFinished(),current()等方法。
◆具体迭代器(ConcreteIterators):在一个特定的对象集,如数组,树,组合,集合等上实现迭代。
通过Traversable接口,PHP原生态支持迭代器模式,这个接口由Iterator和IteratorAggregate做了扩展,这两个子接口不仅是定义了一套标准的方法,每个Traversable对象都可以原封不动地传递给foreach(),foreach是迭代器的主要客户端,Iterator实现是真正的迭代器,而IteratorAggregate是有其它职责的Traversable对象,它通过getIterator()方法返回一个Iterator。

标准PHP库是PHP中绑定的唯一通用目的面向对象库,定义了额外的接口和公用类。OuterIterator实现装饰一个Iterator,CachingIterator和LimitIterator是这个接口的两个例子。
RecursiveIterator是Iterator接口为树形结构实现的一个扩展,它定义了一组额外的方法检查迭代中当前元素的子对象是否存在。RecursiveArrayIterator和RecursiveDirectoryIterator是这个接口的实现示例,这些类型的迭代器可以原样使用,或是用一个RecursiveIteratorIterator桥接到一个普通的迭代器契约。这个OuterIterator实现将会根据构造参数执行深度优先或广度优先遍历。
使用RecursiveIteratorIterator时,可以将其传递给foreach,请看后面的代码示例,了解RecursiveIterators的不同用法和它们的超集Iterator。最后,SeekableIterators向契约添加了一个seek()方法,它可以用于移动Iterator的内部状态到一个特定的迭代点。  
注意,迭代器是比对象集更好的抽象,因为我们可以让InfiniteIterators,NoRewindIterators等,不用与普通数组阵列一致,因此,Iterator缺少count()函数等功能。
在PHP官方手册中可以找到完整的SPL迭代器列表。得益于对PHP的强力支持,使用迭代器模式的大部分工作都包括在标准实现中,下面的代码示例就利用了标准Iterator和RecursiveIterators的功能。
[U]复制代码[/U] 代码如下:
    _content = $content;  
}  
public function rewind()  
{  
     $this->_index = 0;  
}  
public function valid()  
{  
     return isset($this->_content[$this->_index]);  
}  
public function current()  
{  
     return $this->_content[$this->_index];  
}  
public function key()  
{  
     return $this->_index;  
}  
public function next()  
{  
     $this->_index++;  
}  
    }  
    $array = array('A', 'B', 'C', 'D');  
    echo "Collection: ";  
    foreach (new Collection($array) as $key => $value) {  
echo "$key => $value. ";  
    }  
    echo "\n";
    /**  
     * Usually IteratorAggregate is the interface to implement.  
     * It has only one method, which must return an Iterator  
     * already defined as another class (e.g. ArrayIterator)  
     * Iterator gives a finer control over the algorithm,  
     * because all the hook points of Iterator' contract  
     * are available for implementation.  
     */  
    class NumbersSet implements IteratorAggregate  
    {  
private $_content;  
public function __construct(array $content)  
{  
     $this->_content = $content;  
}  
public function contains($number)  
{  
     return in_array($number, $this->_content);  
}  
/**  
  * Only this method is necessary to implement IteratorAggregate.  
  * @return Iterator  
  */  
public function getIterator()  
{  
     return new ArrayIterator($this->_content);  
}  
    }  
    echo "NumbersSet: ";  
    foreach (new NumbersSet($array) as $key => $value) {  
echo "$key => $value. ";  
    }  
    echo "\n";
    // let's play with RecursiveIterator implementations  
    $it = new RecursiveArrayIterator(array(  
'A',  
'B',  
array(  
     'C',  
     'D'  
),  
array(  
     array(  
  'E',  
  'F'  
     ),  
     array(  
  'G',  
  'H',  
  'I'  
     )  
)  
    ));  
    // $it is a RecursiveIterator but also an Iterator,  
    // so it loops normally over the four elements  
    // of the array.  
    echo "Foreach over a RecursiveIterator: ";  
    foreach ($it as $value) {  
echo $value;  
// but RecursiveIterators specify additional  
// methods to explore children nodes  
$children = $it->hasChildren() ? '{Yes}' : '{No}';  
echo $children, ' ';  
    }  
    echo "\n";  
    // we can bridge it to a different contract via  
    // a RecursiveIteratorIterator, whose cryptic name  
    // should be read as 'an Iterator that spans over  
    // a RecursiveIterator'.  
    echo "Foreach over a RecursiveIteratorIterator: ";  
    foreach (new RecursiveIteratorIterator($it) as $value) {  
echo $value;  
    }  
    echo "\n";
            
            
您可能感兴趣的文章:
  • php5.5新数组函数array_column使用
  • php5.5中类级别的常量使用介绍
  • PHP迭代器实现斐波纳契数列的函数
  • PHP迭代器的内部执行过程详解
  • php使用递归与迭代实现快速排序示例
  • PHP5.5在windows安装使用memcached服务端的方法
  • PHP5.5和之前的版本empty函数的不同之处
  • php可应用于面包屑导航的迭代寻找家谱树实现方法
  • 如何把php5.3版本升级到php5.4或者php5.5
  • PHP5.5迭代生成器用法实例详解
            
  • 分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    用户反馈
    客户端