迭代器模式
迭代器模式又称为:Iterator。迭代器是一种行为设计模式,能在不暴露集合底层表现形式(列表、栈和树等)的情况下遍历集合中所有的元素。迭代器模式允许用户通过特定的顺序访问容器中的数据,它将数据和顺序的实现分离,很少有有人直接去用迭代器的了,因为一般语言已经帮实现了如:foreach…,所以单独使用的常见很少了。
问题
需要对数组进行倒序遍历怎么办?
解决方法
前面也说了很多语言已经实现了迭代器,那迭代器是是不是没有用武之地了?其实不然,大部分语言只提供了正序遍历(使用迭代器),在特定场景下是要用到迭代器的,如:对一个数组需要特定(倒序、按元素大小)遍历、对图(深度、广度)遍历等。我们可以使用迭代器模式,对数据进行倒序遍历,语言中 foreach 也是迭代器进行了正序遍历而已。
结构
IterableCollection: 容器接口 定义获取迭代器的方法 ; ConcreteCollection : 实现 IterableCollection 接口的具体容器类 ; Iterator: 迭代器接口 这里定义了 hasMore 和 getNext 方法 ; Concretelterator: 实现 Iterator 接口的具体迭代器类 ;
代码示例
容器接口
代码语言:javascript复制/**
* 容器接口
*/
interface IterableCollection
{
/**
* 创建迭代器
* @return mixed
* @author chendashengpc
*/
public function createIterator();
}
具体容器类
代码语言:javascript复制/**
* 具体容器类
*/
class ConcreteCollection implements IterableCollection
{
public $collection;
public function add($value)
{
$this->collection[] = $value;
}
public function createIterator()
{
return new Concretelterator($this->collection);
}
}
迭代器接口
代码语言:javascript复制/**
* 迭代器接口类
*/
interface Iterator
{
/**
* 获取当前
* @return mixed
* @author chendashengpc
*/
public function getCurrent();
/**
* 获取下一个
* @return mixed
* @author chendashengpc
*/
public function getNext();
/**
* 是否还有更多
* @return bool
* @author chendashengpc
*/
public function hasMore(): bool;
}
具体迭代器类
代码语言:javascript复制/**
* 具体迭代器(倒序迭代器)
*/
class Concretelterator implements Iterator
{
public $collection;
/**
* 索引数
* @var
*/
private int $index;
public function __construct(array $collection)
{
$this->collection = $collection;
$this->index = count($this->collection) - 1;
}
public function getCurrent()
{
if (isset($this->collection[$this->index])) {
return $this->collection[$this->index];
}
return '当前没有元素';
}
public function getNext()
{
--$this->index;
if ($this->hasMore()) {
return $this->collection[$this->index];
}
return '没有元素了';
}
public function hasMore(): bool
{
if (isset($this->collection[$this->index])) {
return true;
}
return false;
}
}
客户端使用
代码语言:javascript复制$collection = new ConcreteCollection();
$collection->add(1);
$collection->add(5);
$collection->add(6);
$collection->add(9);
$iterator = $collection->createIterator();
echo $iterator->getCurrent() . PHP_EOL;
while ($iterator->hasMore()) {
echo $iterator->getNext() . PHP_EOL;
}
输出
代码语言:javascript复制9
6
5
1
没有元素了
php 官方已经提供了,请参考:迭代器
UML
优缺点
优点
- 单一职责原则。通过将体积庞大的遍历算法代码抽取为独立的类,可对客户端代码和集合进行整理。
- 开闭原则。可实现新型的集合和迭代器并将其传递给现有代码,无需修改现有代码。
- 可以并行遍历同一集合,因为每个迭代器对象都包含其自身的遍历状态。
- 相似的,可以暂停遍历并在需要时继续。
缺点
- 对于某些特殊集合,使用迭代器可能比直接遍历的效率低。