• 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
    
  • 相关阅读:
    spark视频-Spark Streaming实时计算和流处理
    spark视频-Spark把云计算大数据速度提高100倍以上
    spark视频-Spark on Docker深入揭秘
    spark视频-Spark as a Service
    spark视频-Spark on Yarn
    MyEclipse Web 项目导入 Eclipse 中需要改的文件
    【解决】小米M1刷机教程(卡刷)
    【解决】笔记本发射WiFi
    【解决】U盘装系统(Win7/Win8)& 装双系统
    【解决】Internet访问看似正常(无叹号受限)却打不开网页
  • 原文地址:https://www.cnblogs.com/zuochuang/p/7246194.html
Copyright © 2020-2023  润新知