第二十章 迭代器模式(想走?可以!先买票)

  1. <?php
  2. //迭代器抽象类
  3. abstract class IteratorClass
  4. {
  5. abstract public function first();
  6. abstract public function next();
  7. abstract public function isDone();
  8. abstract public function currentItem();
  9. }
  10. // 聚集抽象类
  11. abstract class Aggregate
  12. {
  13. abstract function createIterator();
  14. }
  15. class ConcreteIterator extends IteratorClass
  16. {
  17. private $aggregate;
  18. private $current = 0;
  19. function __construct($aggregate)
  20. {
  21. $this->aggregate = $aggregate;
  22. }
  23. public function first()
  24. {
  25. return $this->aggregate[0];
  26. }
  27. public function next()
  28. {
  29. $ret = null;
  30. $this->current++;
  31. if ($this->current < count($this->aggregate))
  32. {
  33. $ret = $this->aggregate[$this->current];
  34. }
  35. return $ret;
  36. }
  37. public function isDone()
  38. {
  39. return $this->current >= count($this->aggregate);
  40. }
  41. public function currentItem()
  42. {
  43. return $this->aggregate[$this->current];
  44. }
  45. }
  46. //这个类的代码感觉不符合书上的写法,但我感觉书上的不对,可能我知识面太单薄,没读懂,可自行参阅原著😊。
  47. class ConcreteAggregate extends Aggregate
  48. {
  49. private $items = [];
  50. public function createIterator()
  51. {
  52. return new ConcreteIterator($this);
  53. }
  54. public function count()
  55. {
  56. return count($this->items);
  57. }
  58. public function add($item)
  59. {
  60. array_push($this->items, $item);
  61. }
  62. public function items()
  63. {
  64. return $this->items;
  65. }
  66. }
  67. //客户端代码
  68. $a = new ConcreteAggregate();
  69. $a->add("大鸟");
  70. $a->add("小菜");
  71. $a->add("行李");
  72. $a->add("老外");
  73. $a->add("公交内部员工");
  74. $a->add("小偷");
  75. $i = new ConcreteIterator($a->items());
  76. while (!$i->isDone())
  77. {
  78. echo $i->currentItem()." 请买票\n";
  79. $i->next();
  80. }

总结:

当你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。

当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式。

为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。

迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合内部的结构,又可让外部代码透明地访问集合内部的数据。