zoukankan      html  css  js  c++  java
  • PHP设计模式之迭代器模式

    概念

    迭代器模式(Iterator),又叫做游标(Cursor)模式。提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

    当你需要访问一个聚合对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑使用迭代器模式。另外,当需要对聚集有多种方式遍历时,可以考虑去使用迭代器模式。迭代器模式为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。

    适用场景

    1. 访问一个聚合对象的内容而无需暴露它的内部表示

    2. 支持对聚合对象的多种遍历

    3. 为遍历不同的聚合结构提供一个统一的接口

    UML图

    角色

    1. Iterator(迭代器):迭代器定义访问和遍历元素的接口

    2. ConcreteIterator(具体迭代器):具体迭代器实现迭代器接口,对该聚合遍历时跟踪当前位置

    3. Aggregate (聚合): 聚合定义创建相应迭代器对象的接口

    4. ConcreteAggregate (具体聚合):具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例

    代码

    代码如下:

    PHP SPL中已经提供了迭代器接口Iterator和容器接口IteatorAggragate,其源码如下:

    /**
     * Interface to detect if a class is traversable using &foreach;.
     * @link http://php.net/manual/en/class.traversable.php
     */
    interface Traversable {
    }
    
    /**
     * Interface to create an external Iterator.
     * @link http://php.net/manual/en/class.iteratoraggregate.php
     */
    interface IteratorAggregate extends Traversable {
    
        /**
         * Retrieve an external iterator
         * @link http://php.net/manual/en/iteratoraggregate.getiterator.php
         * @return Traversable An instance of an object implementing <b>Iterator</b> or
         * <b>Traversable</b>
         * @since 5.0.0
         */
        public function getIterator();
    }
    
    /**
     * Interface for external iterators or objects that can be iterated
     * themselves internally.
     * @link http://php.net/manual/en/class.iterator.php
     */
    interface Iterator extends Traversable {
    
        /**
         * Return the current element
         * @link http://php.net/manual/en/iterator.current.php
         * @return mixed Can return any type.
         * @since 5.0.0
         */
        public function current();
    
        /**
         * Move forward to next element
         * @link http://php.net/manual/en/iterator.next.php
         * @return void Any returned value is ignored.
         * @since 5.0.0
         */
        public function next();
    
        /**
         * Return the key of the current element
         * @link http://php.net/manual/en/iterator.key.php
         * @return mixed scalar on success, or null on failure.
         * @since 5.0.0
         */
        public function key();
    
        /**
         * Checks if current position is valid
         * @link http://php.net/manual/en/iterator.valid.php
         * @return boolean The return value will be casted to boolean and then evaluated.
         * Returns true on success or false on failure.
         * @since 5.0.0
         */
        public function valid();
    
        /**
         * Rewind the Iterator to the first element
         * @link http://php.net/manual/en/iterator.rewind.php
         * @return void Any returned value is ignored.
         * @since 5.0.0
         */
        public function rewind();
    }
    

     这里我们直接实现上面两个接口,请看下面代码:

    <?php
    header('Content-type:text/html;charset=utf-8');
    /**
     * 迭代器模式
     */
    
    /**
     * Class ConcreteIterator 具体的迭代器
     */
    class ConcreteIterator implements Iterator
    {
        private $position = 0;
        private $array = array();
    
        public function __construct($array) {
            $this->array = $array;
            $this->position = 0;
        }
    
        function rewind() {
            $this->position = 0;
        }
    
        function current() {
            return $this->array[$this->position];
        }
    
        function key() {
            return $this->position;
        }
    
        function next() {
            ++$this->position;
        }
    
        function valid() {
            return isset($this->array[$this->position]);
        }
    }
    
    /**
     * Class MyAggregate 聚合容器
     */
    class ConcreteAggregate implements IteratorAggregate
    {
        public $property;
    
        /**
         * 添加属性
         *
         * @param $property
         */
        public function addProperty($property)
        {
            $this->property[] = $property;
        }
    
        public function getIterator()
        {
            return new ConcreteIterator($this->property);
        }
    }
    
    /**
     * Class Client 客户端测试
     */
    class Client
    {
        public static function test()
        {
            //创建一个容器
            $concreteAggregate = new ConcreteAggregate();
            // 添加属性
            $concreteAggregate->addProperty('属性1');
            // 添加属性
            $concreteAggregate->addProperty('属性2');
            //给容器创建迭代器
            $iterator = $concreteAggregate->getIterator();
            //遍历
            while($iterator->valid())
            {
                $key   = $iterator->key();
                $value = $iterator->current();
                echo '键: '.$key.' 值: '.$value.'<hr>';
                $iterator->next();
            }
    
        }
    }
    
    Client:: test();
    

    运行结果:

     
    键: 0 值: 属性1
    键: 1 值: 属性2
    
  • 相关阅读:
    查询程序,统计文件每个单词出现几次,对应的出现在哪一行
    适配器 STL
    非关联容器|hash|unordered_map/multimap,unordered_set/multiset
    函数对象
    ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)
    D. Connected Components Croc Champ 2013
    [Educational Codeforces Round 63 ] D. Beautiful Array (思维+DP)
    C. Vasily the Bear and Sequence Codeforces 336C(枚举,思维)
    Vasya and Beautiful Arrays CodeForces
    D. Happy Tree Party CodeForces 593D【树链剖分,树边权转点权】
  • 原文地址:https://www.cnblogs.com/zuochuang/p/7246194.html
Copyright © 2011-2022 走看看