PHP设计模式漫谈之迭代器模式

原文出处:blogspot

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

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

图1 迭代器模式

参与者:

◆客户端(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的功能。

<?php
/** 

* Collection that wraps a numeric array. 

* All five public methods are needed to implement 

* the Iterator interface. 

*/
class Collection implements Iterator
{
 private $_content;
 private $_index = 0; 

 public function __construct(array $content)
 {
 $this->_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++;
 }
} 

$arrayarray = 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";
时间: 2024-08-29 17:08:44

PHP设计模式漫谈之迭代器模式的相关文章

设计模式C++实现——迭代器模式

模式定义 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露其内部的表示.把游走的任务放在迭代器上,而不是聚合上.这样简化了聚合的接口和实现,也让责任各得其所. 模式结构: Iterator:迭代器定义访问和遍历元素的接口 ConcreteIterator:具体迭代器实现迭代器接口:对该聚合遍历时跟踪当前位置 Aggregate:聚合定义创建相应的迭代器对象接口 ConcreteAggregate:具体聚合实现

设计模式入门之迭代器模式Iterator

迭代器模式定义:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部实现 迭代器模式的结构和说明 Iterator::迭代器接口.定义访问和遍历元素的接口 ConcreteIterator:具体的迭代器实现对象.实现对聚合对象的遍历,并跟踪遍历时的当前位置 Aggregate:聚合对象.定义创建相应迭代器对象的接口 ConcreteAggregate:具体聚合对象.实现创建相应的迭代器对象 实例:一个公司,工资列表是用List实现的,后收购一家公司,工资列表是用Array实现

Java设计模式学习记录-迭代器模式

前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/O的各种实现用到了什么设计模式,我愣是想半天没想出来了,人家还给提示了我也没想出来,最后还是面试官给出的答案,是装饰模式,听到答案后就恍然大悟了,前两天刚看了装饰模式,还写下了I/O操作中的各种类都是用到了装饰模式,后来想想两方面原因造成的当时没回答出来,一是面试时紧张就容易想不起来,二是对设计模式

设计模式之三:迭代器模式(IteratorPattern)

迭代器(Iterator)模式,又叫游标(Cursor)模式.其定义为:提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节.迭代器模式是和容器相关的,对容器对象的访问设计到遍历算法. 迭代器模式由以下角色组成: 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口. 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并记录遍历中的当前位置. 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口. 具体容器

javascript设计模式学习之七——迭代器模式

一.迭代器模式定义 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,并且不需要暴露该对象的内部表示. 在当前大部分语言中,都已经内置了迭代器模式.迭代器有内部迭代器和外部迭代器之分,一般现有语言中实现的大多是内部迭代器. 二.jquery中的each实现 //类似jquery中的each迭代器 $.each=function(obj,callback){ var value, i=0, isArray=isArrayLike(obj), length=obj.length; if(isA

Java设计模式系列之迭代器模式

迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 迭代器模式的角色构成 (1)迭代器角色(Iterator):定义遍历元素所需要的方法,一般来说会有这么三个方法:取得下一个元素的方法next(),判断是否遍历结束的方法hasNext()),移出当前对象的方法remove(), (2)具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代. (3)容器角色(Aggregate): 

23种设计模式中的迭代器模式

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个对象. 那么如何提供一个方法顺序呢? public interface Iterator<T>{ public boolean hasNext(); public T next(); } public class XXX{ private List<XXX> list =new ArrayList<>(); public Iterator getIterator (){ return new XXXIterator()

设计模式整理_迭代器模式

迭代器模式提供了一种方法顺序访问一个聚合对象中的各个元素,而又不是暴露其内部的表示.将在聚合对象内部游走的任务放在迭代器上而不是放在聚合上,这样简化了聚合的接口和实现,也让责任各得其所. 例如在没有进行优化的下列代码中,在处理不同的对象的聚合的时候,获取了对象的内部实现,这对封装造成了破坏,另外一方面,当需要处理其他类型的聚合对象的时候,也会造成需要对源代码进行修改,不利于扩展. /* * 定义Food类,Food类是需要被聚合的对象 * */ public class Food { priva

Java设计模式8:迭代器模式

迭代器模式 迭代器模式又叫做游标(Cursor)模式,其作用是提供一种方法访问一个容器元素中的各个对象,而又不暴露该对象的内部细节. 迭代器模式结构 迭代器模式由以下角色组成: 1.迭代器角色 负责定义访问和遍历元素的接口 2.具体迭代器角色 实现迭代器接口,并要记录遍历中的当前位置 3.容器角色 负责提供创建具体迭代器角色的接口 4.具体容器角色 实现创建具体迭代器角色的接口,这个具体迭代器角色与该容器的结构相关 迭代器模式在JDK中的应用及解读 迭代器模式就不自己写例子了,直接使用JDK中的