若转载教程,请注明出自SW-X框架官方文档1

    1. <?php
    2. /**
    3. * 设计模式之迭代器模式
    4. * 场景:指针读取 - 先进先出,后进后出
    5. * 小黄牛
    6. */
    7. header("Content-type: text/html; charset=utf-8");
    8. /**
    9. * 接口 迭代器
    10. */
    11. interface IIterator{
    12. public function First(); // 首元素
    13. public function Next(); // 下一个元素
    14. public function IsDone(); // 是否已结束
    15. public function CurrentItem(); // 当前元素
    16. public function CurrentIdx(); // 当前指针
    17. }
    18. /**
    19. * 抽象 容器
    20. */
    21. abstract class Aggregate{
    22. protected $IIter; // 迭代器的实例
    23. /**
    24. * 选择容器对应的迭代器
    25. */
    26. public function __construct($New){
    27. $this->IIter = $New;
    28. }
    29. /**
    30. * 将容器的this传给 迭代器,并返回迭代器的当前实例
    31. */
    32. abstract public function CreateIterator();
    33. }
    34. /**
    35. * 创建一个 - 具体容器
    36. */
    37. class MyAggregate extends Aggregate{
    38. public $Items = array(); // 数据存储内容
    39. # 容器的迭代器
    40. public function CreateIterator(){
    41. return $this->IIter->GetAg($this);
    42. }
    43. # 获得指定容器内容
    44. public function GetItem($idx){
    45. return isset($this->Items[$idx]) ? $this->Items[$idx] : null;
    46. }
    47. # 修改容器内容
    48. public function SetItem($idx,$val){
    49. $this->Items[$idx] = $val;
    50. }
    51. # 获得容器内容长度
    52. public function GetCount(){
    53. return count($this->Items);
    54. }
    55. }
    56. /**
    57. * 创建一个 - 具体迭代器
    58. */
    59. class MineIterator implements IIterator{
    60. //容器【聚集对象】
    61. private $aggregate; // 容器的实例
    62. private $current = 0; // 容器内的数据长度
    63. # 为迭代器注入容器
    64. public function GetAg($aggregate){
    65. $this->aggregate = $aggregate;
    66. return $this;
    67. }
    68. # 获取首元素
    69. public function First(){
    70. return $this->aggregate->GetItem(0);
    71. }
    72. # 下一个元素内容
    73. public function Next(){
    74. $this->current++;
    75. # 在这一步你也可以设置成指针向下,并获取下一个元素内容
    76. }
    77. # 是否已结束 - 已无内容
    78. public function IsDone() {
    79. return ($this->current >= $this->aggregate->GetCount()) ? true : false;
    80. }
    81. # 获取当前元素
    82. public function CurrentItem(){
    83. return $this->aggregate->GetItem($this->current);
    84. }
    85. # 获取当前元素长度
    86. public function CurrentIdx() {
    87. return $this->current;
    88. }
    89. }
    90. # 创建一个容器
    91. $myAggregate = new MyAggregate(new MineIterator());
    92. # 向容器中添加元素
    93. $myAggregate->SetItem(0,'小黄牛');
    94. $myAggregate->SetItem(1,'小黄狗');
    95. $myAggregate->SetItem(2,'小黄猪');
    96. # 迭代器注入容器内容
    97. $iterator = $myAggregate->CreateIterator();
    98. # 还有内容,就一直遍历
    99. while(!$iterator->IsDone()) {
    100. $idx = $iterator->CurrentIdx(); // 获得元素当前位置长度
    101. $item = $iterator->CurrentItem(); // 获取当前元素内容
    102. echo "当前位置:{$idx},值:{$item}<br/>";
    103. $iterator->Next(); // 将指针指向下一个元素,否则将会出现死循环
    104. }

    浏览器输出

    1. 当前位置:0,值:小黄牛
    2. 当前位置:1,值:小黄狗
    3. 当前位置:2,值:小黄猪

    迭代器模式

    1. Iterator(迭代器):迭代器定义访问和遍历元素的接口
    2. ConcreteIterator(具体迭代器):具体迭代器实现迭代器接口,对该聚合遍历时跟踪当前位置
    3. Aggregate (聚合):聚合定义创建相应迭代器对象的接口(可选)
    4. ConcreteAggregate(具体聚合):具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例(可选)

    使用场景

    1. 1.访问一个聚合对象的内容而无需暴露它的内部表示
    2. 2.支持对聚合对象的多种遍历
    3. 3.为遍历不同的聚合结构提供一个统一的接口
    4. 4.队列或按照指针循环读取的情况下