• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

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

php 搞代码 4年前 (2022-01-26) 22次浏览 已收录 0个评论

迭代器(Iterator)模式,它在一个很常见的过程上提供了一个抽象:位于对象图不明部分的一组对象(或标量)集合上的迭代。迭代有几种不同的具体执行方法:在数组属性,集合对象,数组,甚至一个查询结果集之上迭代。

在对象的世界里,迭代器模式要维持类似数组的功能,看作是一个非侵入性对象刻面(facet),Client类往往分离自真实对象实现,指iterator接口。只要有可能,我们可以给迭代器传送一个引用,代替将来可能发生变化的具体或抽象类。

参与者:
◆客户端(Client):
引用迭代器模式的方法在一组值或对象上执行一个循环。
◆迭代器(Iterator):在迭代过程上的抽象,包括next(),isFinished(),current()等方法。
◆具体迭代器(ConcreteIterators):在一个特定的对象集,如数组,树,组合,集合等上实现迭本@文来源[email protected]搞@^&代*@码网(搞代gaodaima码代。
通过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的功能。

    <?php <BR>    /**  <BR>     * Collection that wraps a numeric array.  <BR>     * All five public methods are needed to implement  <BR>     * the Iterator interface.  <BR>     */  <BR>    class Collection implements Iterator  <BR>    {  <BR> private $_content;  <BR> private $_index = 0;  <br><br> public function __construct(array $content)  <BR> {  <BR>     $this->_content = $content;  <BR> }  <br><br> public function rewind()  <BR> {  <BR>     $this->_index = 0;  <BR> }  <br><br> public function valid()  <BR> {  <BR>     return isset($this->_content[$this->_index]);  <BR> }  <br><br> public function current()  <BR> {  <BR>     return $this->_content[$this->_index];  <BR> }  <br><br> public function key()  <BR> {  <BR>     return $this->_index;  <BR> }  <br><br> public function next()  <BR> {  <BR>     $this->_index++;  <BR> }  <BR>    }  <br><br>    $array = array('A', 'B', 'C', 'D');  <BR>    echo "Collection: ";  <BR>    foreach (new Collection($array) as $key => $value) {  <BR> echo "$key => $value. ";  <BR>    }  <BR>    echo "\n"; <BR>    /**  <BR>     * Usually IteratorAggregate is the interface to implement.  <BR>     * It has only one method, which must return an Iterator  <BR>     * already defined as another class (e.g. ArrayIterator)  <BR>     * Iterator gives a finer control over the algorithm,  <BR>     * because all the hook points of Iterator' contract  <BR>     * are available for implementation.  <BR>     */  <BR>    class NumbersSet implements IteratorAggregate  <BR>    {  <BR> private $_content;  <br><br> public function __construct(array $content)  <BR> {  <BR>     $this->_content = $content;  <BR> }  <br><br> public function contains($number)  <BR> {  <BR>     return in_array($number, $this->_content);  <BR> }  <br><br> /**  <BR>  * Only this method is necessary to implement IteratorAggregate.  <BR>  * @return Iterator  <BR>  */  <BR> public function getIterator()  <BR> {  <BR>     return new ArrayIterator($this->_content);  <BR> }  <BR>    }  <br><br>    echo "NumbersSet: ";  <BR>    foreach (new NumbersSet($array) as $key => $value) {  <BR> echo "$key => $value. ";  <BR>    }  <BR>    echo "\n"; <BR>    // let's play with RecursiveIterator implementations  <BR>    $it = new RecursiveArrayIterator(array(  <BR> 'A',  <BR> 'B',  <BR> array(  <BR>     'C',  <BR>     'D'  <BR> ),  <BR> array(  <BR>     array(  <BR>  'E',  <BR>  'F'  <BR>     ),  <BR>     array(  <BR>  'G',  <BR>  'H',  <BR>  'I'  <BR>     )  <BR> )  <BR>    ));  <BR>    // $it is a RecursiveIterator but also an Iterator,  <BR>    // so it loops normally over the four elements  <BR>    // of the array.  <BR>    echo "Foreach over a RecursiveIterator: ";  <BR>    foreach ($it as $value) {  <BR> echo $value;  <BR> // but RecursiveIterators specify additional  <BR> // methods to explore children nodes  <BR> $children = $it->hasChildren() ? '{Yes}' : '{No}';  <BR> echo $children, ' ';  <BR>    }  <BR>    echo "\n";  <BR>    // we can bridge it to a different contract via  <BR>    // a RecursiveIteratorIterator, whose cryptic name  <BR>    // should be read as 'an Iterator that spans over  <BR>    // a RecursiveIterator'.  <BR>    echo "Foreach over a RecursiveIteratorIterator: ";  <BR>    foreach (new RecursiveIteratorIterator($it) as $value) {  <BR> echo $value;  <BR>    }  <BR>    echo "\n"; <BR>

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:PHP设计模式之迭代器模式的深入解析_php技巧
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址