AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
# (\*)迭代器模式(Iterator) > 迭代器模式 (Iterator),又叫做游标(Cursor)模式。提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。就像一个双色球彩票开奖一 样,每次都是摇出七个球,不能能摇不是七个球的中奖号码组合。概括为提供一种方法访问一个容器(Container)对象中各个元素,而又不需暴露该对象的内部细节。 **优点:** 1. 访问一个聚合对象的内容而无须暴露它的内部表示。 2. 遍历任务交由迭代器完成,这简化了聚合类。 3. 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。 4. 增加新的聚合类和迭代器类都很方便,无须修改原有代码。 5. 封装性良好,为遍历不同的聚合结构提供一个统一的接口。 **缺点:** - 每次遍历都是整个集合,不能单独取出元素。增加了类的个数,这在一定程度上增加了系统的复杂性。 **应用场景:** 需要操作集合里的全部元素 当你需要访问一个聚合对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑使用迭代器模式。另外,当需要对聚集有多种方式遍历时,可以考虑去使用迭代器模式。迭代器模式为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口 **实际应用:** 如[Java](http://c.biancheng.net/java/)语言中的 Collection、List、Set、Map 等都包含了迭代器 ## **模式的结构** 1. 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。 2. 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。 3. 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。 4. 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。 ![](https://img.kancloud.cn/fb/52/fb52c04e872fce60d6979f9da28a75eb_521x376.png) ``` <pre class="calibre10">``` <span class="token">//抽象聚合</span> interface <span class="token4">Aggregate</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">add</span><span class="token3">(</span>$obj<span class="token3">)</span><span class="token3">;</span> public <span class="token5">function</span> <span class="token4">remove</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">/** * * @return Iterator [description] */</span> public <span class="token5">function</span> <span class="token4">getIterator</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//具体聚合</span> class <span class="token4">ConcreteAggregate</span> implements <span class="token4">Aggregate</span> <span class="token3">{</span> private $list<span class="token1">=</span><span class="token4">array</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> public <span class="token5">function</span> <span class="token4">add</span><span class="token3">(</span>$obj<span class="token3">)</span> <span class="token3">{</span> <span class="token">//尾部插入一个或多个新单元(入栈) </span> <span class="token4">array_push</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>list<span class="token3">,</span> $obj<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">remove</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token4">array_pop</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>list<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">/** * * @return Iterator [description] */</span> public <span class="token5">function</span> <span class="token4">getIterator</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span><span class="token3">(</span><span class="token5">new</span> <span class="token4">ConcreteIterator</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>list<span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">//抽象迭代器(多个I因为php系统已有Iterator类)</span> interface <span class="token4">IIterator</span> <span class="token3">{</span> <span class="token5">function</span> <span class="token4">first</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token5">function</span> <span class="token4">next</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token5">function</span> <span class="token4">hasNext</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">//具体迭代器</span> class <span class="token4">ConcreteIterator</span> implements <span class="token4">IIterator</span> <span class="token3">{</span> private $list<span class="token1">=</span><span class="token4">array</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> private $index<span class="token1">=</span><span class="token1">-</span><span class="token6">1</span><span class="token3">;</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span>array $list<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>list<span class="token1">=</span>$list<span class="token3">;</span> <span class="token3">}</span> <span class="token">/** * * @return boolean [description] */</span> public <span class="token5">function</span> <span class="token4">hasNext</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">if</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>index <span class="token1"><</span> <span class="token4">count</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>list<span class="token3">)</span><span class="token1">-</span><span class="token6">1</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> <span class="token6">true</span><span class="token3">;</span> <span class="token3">}</span><span class="token5">else</span><span class="token3">{</span> <span class="token5">return</span> <span class="token6">false</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">first</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>index<span class="token1">=</span><span class="token6">0</span><span class="token3">;</span> $obj<span class="token1">=</span>$this<span class="token1">-</span><span class="token1">></span>list<span class="token3">[</span>$this<span class="token1">-</span><span class="token1">></span>index<span class="token3">]</span><span class="token3">;</span> <span class="token5">return</span> $obj<span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">next</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> $obj<span class="token1">=</span><span class="token5">null</span><span class="token3">;</span> <span class="token5">if</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span><span class="token4">hasNext</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> $obj<span class="token1">=</span>$this<span class="token1">-</span><span class="token1">></span>list<span class="token3">[</span><span class="token1">++</span>$this<span class="token1">-</span><span class="token1">></span>index<span class="token3">]</span><span class="token3">;</span> <span class="token">//$this->index += 1</span> <span class="token">//$obj=$this->list[$this->index]</span> <span class="token3">}</span> <span class="token5">return</span> $obj<span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">Client</span> <span class="token3">{</span> public static <span class="token5">function</span> <span class="token4">main</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> $Aggregate<span class="token1">=</span><span class="token5">new</span> <span class="token4">ConcreteAggregate</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $Aggregate<span class="token1">-</span><span class="token1">></span><span class="token4">add</span><span class="token3">(</span><span class="token2">"中山大学"</span><span class="token3">)</span><span class="token3">;</span> $Aggregate<span class="token1">-</span><span class="token1">></span><span class="token4">add</span><span class="token3">(</span><span class="token2">"华南理工"</span><span class="token3">)</span><span class="token3">;</span> $Aggregate<span class="token1">-</span><span class="token1">></span><span class="token4">add</span><span class="token3">(</span><span class="token2">"韶关学院"</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span><span class="token2">"聚合的内容有:<br>"</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//获取迭代器</span> $Iterator<span class="token1">=</span>$Aggregate<span class="token1">-</span><span class="token1">></span><span class="token4">getIterator</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//遍历迭代器</span> <span class="token5">while</span><span class="token3">(</span>$Iterator<span class="token1">-</span><span class="token1">></span><span class="token4">hasNext</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span> <span class="token3">{</span> $ob<span class="token1">=</span>$Iterator<span class="token1">-</span><span class="token1">></span><span class="token4">next</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span><span class="token2">"--"</span><span class="token3">.</span>$ob<span class="token3">.</span><span class="token2">"--<br>"</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> $ob<span class="token1">=</span>$Iterator<span class="token1">-</span><span class="token1">></span><span class="token4">first</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">print_r</span><span class="token3">(</span><span class="token2">"First:"</span><span class="token3">.</span>$ob<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> Client<span class="token3">:</span><span class="token3">:</span><span class="token4">main</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> 输出: 聚合的内容有: <span class="token1">--</span>中山大学<span class="token1">--</span> <span class="token1">--</span>华南理工<span class="token1">--</span> <span class="token1">--</span>韶关学院<span class="token1">--</span> First:中山大学 ``` ``` php标准库(SPL)中提供了迭代器接口 Iterator,要实现迭代器模式,实现该接口即可。 ``` <pre class="calibre10">``` class <span class="token4">sample</span> implements <span class="token4">Iterator</span> <span class="token3">{</span> private $_items <span class="token3">;</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span><span class="token1">&</span>$data<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>_items <span class="token1">=</span> $data<span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">current</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> <span class="token4">current</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>_items<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">next</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token4">next</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>_items<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">key</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> <span class="token4">key</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>_items<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">rewind</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token4">reset</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>_items<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">valid</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> <span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span><span class="token4">current</span><span class="token3">(</span><span class="token3">)</span> <span class="token1">!==</span> FALSE<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> <span class="token">// client</span> $data <span class="token1">=</span> <span class="token4">array</span><span class="token3">(</span><span class="token6">1</span><span class="token3">,</span> <span class="token6">2</span><span class="token3">,</span> <span class="token6">3</span><span class="token3">,</span> <span class="token6">4</span><span class="token3">,</span> <span class="token6">5</span><span class="token3">)</span><span class="token3">;</span> $sa <span class="token1">=</span> <span class="token5">new</span> <span class="token4">sample</span><span class="token3">(</span>$data<span class="token3">)</span><span class="token3">;</span> foreach <span class="token3">(</span>$sa AS $key <span class="token1">=</span><span class="token1">></span> $row<span class="token3">)</span> <span class="token3">{</span> echo $key<span class="token3">,</span> <span class="token2">' '</span><span class="token3">,</span> $row<span class="token3">,</span> <span class="token2">'<br />'</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">/* 输出: 0 1 1 2 2 3 3 4 4 5 */</span> ``` ``` Yii FrameWork Demo ``` <pre class="calibre17">``` class <span class="token4">CMapIterator</span> implements <span class="token4">Iterator</span> <span class="token3">{</span> <span class="token">/** * @var array the data to be iterated through */</span> private $_d<span class="token3">;</span> <span class="token">/** * @var array list of keys in the map */</span> private $_keys<span class="token3">;</span> <span class="token">/** * @var mixed current key */</span> private $_key<span class="token3">;</span> <span class="token">/** * Constructor. * @param array the data to be iterated through */</span> public <span class="token5">function</span> <span class="token4">__construct</span><span class="token3">(</span><span class="token1">&</span>$data<span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>_d<span class="token1">=</span><span class="token1">&</span>$data<span class="token3">;</span> $this<span class="token1">-</span><span class="token1">></span>_keys<span class="token1">=</span><span class="token4">array_keys</span><span class="token3">(</span>$data<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">/** * Rewinds internal array pointer. * This method is required by the interface Iterator. */</span> public <span class="token5">function</span> <span class="token4">rewind</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>_key<span class="token1">=</span><span class="token4">reset</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>_keys<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">/** * Returns the key of the current array element. * This method is required by the interface Iterator. * @return mixed the key of the current array element */</span> public <span class="token5">function</span> <span class="token4">key</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>_key<span class="token3">;</span> <span class="token3">}</span> <span class="token">/** * Returns the current array element. * This method is required by the interface Iterator. * @return mixed the current array element */</span> public <span class="token5">function</span> <span class="token4">current</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>_d<span class="token3">[</span>$this<span class="token1">-</span><span class="token1">></span>_key<span class="token3">]</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">/** * Moves the internal pointer to the next array element. * This method is required by the interface Iterator. */</span> public <span class="token5">function</span> <span class="token4">next</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> $this<span class="token1">-</span><span class="token1">></span>_key<span class="token1">=</span><span class="token4">next</span><span class="token3">(</span>$this<span class="token1">-</span><span class="token1">></span>_keys<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">/** * Returns whether there is an element at current position. * This method is required by the interface Iterator. * @return boolean */</span> public <span class="token5">function</span> <span class="token4">valid</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> $this<span class="token1">-</span><span class="token1">></span>_key<span class="token1">!==</span><span class="token6">false</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> $data <span class="token1">=</span> <span class="token4">array</span><span class="token3">(</span><span class="token2">'s1'</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">11</span><span class="token3">,</span> <span class="token2">'s2'</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">22</span><span class="token3">,</span> <span class="token2">'s3'</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">33</span><span class="token3">)</span><span class="token3">;</span> $it <span class="token1">=</span> <span class="token5">new</span> <span class="token4">CMapIterator</span><span class="token3">(</span>$data<span class="token3">)</span><span class="token3">;</span> foreach <span class="token3">(</span>$it as $row<span class="token3">)</span> <span class="token3">{</span> echo $row<span class="token3">,</span> <span class="token2">'<br />'</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">/* 输出: 11 22 33 */</span> ``` ```