源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

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

  • 时间:2021-01-15 23:36 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:PHP设计模式之迭代器模式的深入解析
迭代器(Iterator)模式,它在一个很常见的过程上提供了一个抽象:位于对象图不明部分的一组对象(或标量)集合上的迭代。迭代有几种不同的具体执行方法:在数组属性,集合对象,数组,甚至一个查询结果集之上迭代。 在对象的世界里,迭代器模式要维持类似数组的功能,看作是一个非侵入性对象刻面(facet),Client类往往分离自真实对象实现,指iterator接口。只要有可能,我们可以给迭代器传送一个引用,代替将来可能发生变化的具体或抽象类。 [img]http://files.jb51.net/file_images/article/201306/2013061315545912.jpg[/img] [b]参与者: ◆客户端(Client):[/b]引用迭代器模式的方法在一组值或对象上执行一个循环。 [b]◆迭代器(Iterator):[/b]在迭代过程上的抽象,包括next(),isFinished(),current()等方法。 [b]◆具体迭代器(ConcreteIterators):[/b]在一个特定的对象集,如数组,树,组合,集合等上实现迭代。 通过Traversable接口,PHP原生态支持迭代器模式,这个接口由Iterator和IteratorAggregate做了扩展,这两个子接口不仅是定义了一套标准的方法,每个Traversable对象都可以原封不动地传递给foreach(),foreach是迭代器的主要客户端,Iterator实现是真正的迭代器,而IteratorAggregate是有其它职责的Traversable对象,它通过getIterator()方法返回一个Iterator。 [img]http://files.jb51.net/file_images/article/201306/2013061315545913.jpg[/img] 标准PHP库是PHP中绑定的唯一通用目的面向对象库,定义了额外的接口和公用类。OuterIterator实现装饰一个Iterator,CachingIterator和LimitIterator是这个接口的两个例子。 RecursiveIterator是Iterator接口为树形结构实现的一个扩展,它定义了一组额外的方法检查迭代中当前元素的子对象是否存在。RecursiveArrayIterator和RecursiveDirectoryIterator是这个接口的实现示例,这些类型的迭代器可以原样使用,或是用一个RecursiveIteratorIterator桥接到一个普通的迭代器契约。这个OuterIterator实现将会根据构造参数执行深度优先或广度优先遍历。 使用RecursiveIteratorIterator时,可以将其传递给foreach,请看后面的代码示例,了解RecursiveIterators的不同用法和它们的超集Iterator。最后,SeekableIterators向契约添加了一个seek()方法,它可以用于移动Iterator的内部状态到一个特定的迭代点。  [b]注意[/b],迭代器是比对象集更好的抽象,因为我们可以让InfiniteIterators,NoRewindIterators等,不用与普通数组阵列一致,因此,Iterator缺少count()函数等功能。 在PHP官方手册中可以找到完整的SPL迭代器列表。得益于对PHP的强力支持,使用迭代器模式的大部分工作都包括在标准实现中,下面的代码示例就利用了标准Iterator和RecursiveIterators的功能。
[u]复制代码[/u] 代码如下:
    <?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++;   }      }      $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";
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部