初始迭代器模式
迭代器模式提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。在《大话设计模式》中提到,此设计模式实用价值远不如学习价值大了,martin flower甚至提出撤销此设计模式。另外,无论是JAVA、Python,亦或是PHP中,都存在多种多样的遍历聚合元素的方式,所以此处就不过多的去了解了。这里我主要记录的是自己对PHP迭代器Iterator的抽象类的使用。
PHP中的迭代器
PHP中的迭代器有好几种,但是初始接口都是“iterable”,另外,由于PHP中的迭代器众多,我得精力有限,不可能学习所有的迭代器,以后有需要再补充。主要学习了几个主要的。另外,这里记录一下我知道的迭代器的类名。
Iterator::class;
IteratorIterator::class;
IteratorAggregate::class;
ArrayIterator::class;
APCIterator::class;
APCUIterator::class;
AppendIterator::class;
CachingIterator::class;
CallbackFilterIterator::class;
DirectoryIterator::class;
EmptyIterator::class;
FilesystemIterator::class;
FilterIterator::class;
GlobIterator::class;
ImagickPixelIterator::class;
InfiniteIterator::class;
IntlBreakIterator::class;
IntlCodePointBreakIterator::class;
IntlIterator::class;
IntlRuleBasedBreakIterator::class;
LimitIterator::class;
MultipleIterator::class;
NoRewindIterator::class;
OuterIterator::class;
ParentIterator::class;
RecursiveArrayIterator::class;
RecursiveCachingIterator::class;
RecursiveCallbackFilterIterator::class;
RecursiveDirectoryIterator::class;
RecursiveFilterIterator::class;
RecursiveIterator::class;
RecursiveRegexIterator::class;
RecursiveTreeIterator::class;
RegexIterator::class;
SeekableIterator::class;
SimpleXMLIterator::class;
RecursiveIteratorIterator::class;
Iterator(普通迭代器)
Iterator属于PHP中最简单的迭代器,实现的方法也很简单,只需要实现Iterator接口中存在的5个抽象方法即可。代码如下:
<?php
class Iterator01 implements Iterator
{
private $data;
private $position = 0;
public function __construct($data, $position = 0)
{
$this->data = $data;
$this->position = $position;
}
public function current()
{
if ($this->valid()) {
return $this->data[$this->position];
}
return null;
}
public function key()
{
return $this->position;
}
public function next()
{
$this->position++;
if ($this->valid()) {
return $this->current();
}
return null;
}
public function rewind()
{
return $this->position = 0;
}
public function valid()
{
return $this->position>=0 && $this->position<count($this->data);
}
}
$array = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
$iterator = new Iterator01($array);
echo $iterator->current();
for ($i=0; $i<100; $i++) {
echo $iterator->next();
}
IteratorIterator(迭代“迭代器”)
IteratorIterator在网上的资料比较少,看手册又看不懂。简单的记录一下学习到的吧。IteratorIterator主要作用是用来迭代迭代器的。它可以通过控制InnerIterator来实现不同的逻辑操作。上代码:
<?php
//Iterator
class MyIterator implements Iterator
{
public function valid()
{
echo __METHOD__ . '<br/>';
return false;
}
public function rewind()
{
echo __METHOD__ . '<br/>';
}
public function next()
{
echo __METHOD__ . '<br/>';
}
public function key()
{
echo __METHOD__ . '<br/>';
}
public function current()
{
echo __METHOD__ . '<br/>';
}
}
//IteratorIterator
class MyIteratorIterator extends IteratorIterator
{
public function getInnerIterator()
{
parent::getInnerIterator();
}
public function current()
{
echo __METHOD__ . '<br/>';
parent::current();
}
public function key()
{
echo __METHOD__ . '<br/>';
parent::key();
}
public function next()
{
echo __METHOD__ . '<br/>';
parent::next();
}
public function rewind()
{
echo __METHOD__ . '<br/>';
parent::rewind();
}
public function valid()
{
echo __METHOD__ . '<br/>';
parent::valid();
}
}
$arr = ['A' => 'AA', 'B' => 'BB', 'C' => 'CC', 'D' => 'DD', 'E' => 'EE', 'F' => 'FF', 'G' => 'GG'];
$myIterator = new MyIterator($arr);
$myIteratorIterator = new MyIteratorIterator(new MyIterator($arr));
echo '当前调用的是current方法:<br/>';
$myIteratorIterator->current();
echo '<hr/>';
echo '当前调用的是next方法:<br/>';
$myIteratorIterator->next();
echo '<hr/>';
echo '当前调用的是key方法:<br/>';
$myIteratorIterator->key();
echo '<hr/>';
echo '当前调用的是valid方法:<br/>';
$myIteratorIterator->valid();
echo '<hr/>';
echo '当前调用的是rewind方法:<br/>';
$myIteratorIterator->rewind();
echo '<hr/>';
上述方法只可以迭代显示以连续数字为key的数组:
如果MyIterator中的valid返回的是false,则返回结果为:
最后总结如下:IteratorIterator在调用next、rewind这两个移动指针的方法时,会主动的调用参数迭代器(我得例子中是MyIterator),调用的顺序为:
(1) IteratorIterator::next-->InnerIterator::next-->InnerIterator::valid(返回值为false)
(2) IteratorIterator::next-->InnerIterator::next-->InnerIterator::valid(返回值为true)-->InnerIterator::current-->InnerIterator::key
(1) IteratorIterator::rewind-->InnerIterator::next-->InnerIterator::valid(返回值为false)
(1) IteratorIterator::rewind-->InnerIterator::next-->InnerIterator::valid(返回值为false)-->InnerIterator::current-->InnerIterator::key
在网上找资料的时候看到了一个大神的博客,关于IteratorIterator的,地址:https://blog.csdn.net/hxx_yang/article/details/82915634。先把大神的结果粘在这里,防止博客牵走。
Outer的每次迭代会先调用自己的方法,然后转发给Inner。
Outer内部方法的返回值都是基于Inner的相对于方法的返回。
你可以在Outer内方法对Inner的返回值做逻辑处理。
当Inner的valid返回false的时候,外层的Outer也将停止迭代。
Outer内的方法对返回值的修改并不会影响Inner。
Outer内的方法在迭代过程中并不会执行getInnerIterator方法,它只是一个获取Inner方法的调用接口。
ArrayIterator(数组迭代器)
最后介绍一个数组迭代器,类似于next()、current()等一系列的指针函数,也可以用来遍历数据。
<?php
$arr = ['A' => 'AA', 'B' => 'BB', 'C' => 'CC', 'D' => 'DD', 'E' => 'EE', 'F' => 'FF', 'G' => 'GG'];
$arrIterator = new ArrayIterator($arr);
while ($arrIterator->valid()) {
echo $arrIterator->current();
$arrIterator->next();
echo '<br/>';
}
var_dump(iterator_to_array($arrIterator));
鸣谢
非常感谢此CSDN博主的文章,让我学到了不少,地址附上了https://blog.csdn.net/hxx_yang/article/details/82915634。
参考资料
下一篇
初识设计模式——单例模式