迭代器模式 - Iterator Pattern
定义
提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示。
设计的原则和思想
- 解耦使用者和集合类对象。
- 不变部分是迭代器,变化部分是集合对象。
- 核心思想是让对象能像数组一样能遍历。
一句话概括设计模式
遍历对象。
结构中包含的角色
- Iterator(抽象迭代器)
- ConcreteIterator(具体迭代器)
- IteratorAggregate(抽象聚合类)
- ConcreteIteratorAggregate(具体聚合类)
最小可表达代码
// 抽象迭代器
abstract class AbstractIterator implements Iterator
{
private $position = 0; // 游标
private $objects = [];
public function __construct(array $objects)
{
$this->position = 0;
$this->objects = $objects;
}
public function current()
{
return $this->objects[$this->position];
}
public function next()
{
++$this->position;
}
public function key()
{
return $this->position;
}
public function valid()
{
return isset($this->objects[$this->position]);
}
public function rewind()
{
$this->position = 0;
}
}
// 具体迭代器
class ConcreteIterator extends AbstractIterator{}
// 具体聚合类
class ConcreteIteratorAggregate implements IteratorAggregate
{
private $objects;
public function __construct(array $objects)
{
$this->objects = $objects;
}
public function getIterator()
{
return new ConcreteIterator($this->objects);
}
}
$objects = ['张3', '李4'];
$aggregate = new ConcreteIteratorAggregate($objects);
foreach ($aggregate->getIterator() as $key => $value) {
var_dump($key, $value);
}
优点
- 支持遍历一个聚合对象。
- 在同一个聚合上可以有多个遍历。
- 增加新的聚合类和迭代器类都很方便,无须修改原有代码。
- 可以暂停遍历并在需要时继续。
缺点
- 增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
- 迭代器比直接遍历的效率低。
- 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展.
何时使用
- 为一个聚合对象提供多种遍历方式(访问集合元素的方法)而无须暴露它的内部表示。
- 如果你希望代码能够遍历不同的甚至是无法预知的数据结构, 可以使用迭代器模式。
实际应用场景
- Laravel的Collection类