迭代器模式 - 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类