迭代器模式结构:
![]()
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
8 namespace DesignPattern.BehavioralPattern
9 {
10 #region 迭代器模式要点
11 //定义:提供顺序访问聚合对象内部元素的方式,而又无需暴露其内部表示。
12 //主要思想是将集合的遍历行为抽取为单独的迭代器对象。
13 //应用场景:
14 //1.当集合背后为复杂的数据结构,且你希望对客户端隐藏其复杂性时(出于使用便利性或安全性的考虑)。
15 //2.使用该模式可以减少程序中重复的遍历代码。
16 //3. 如果你希望代码能够遍历不同的甚至是无法预知的数据结构,该模式为集合和迭代器提供了一些通用接口。
17 //
18 //实现方式:
19 //1.声明迭代器接口。 该接口必须提供至少一个方法来获取集合中的下个元素。
20 //还可以添加其他方法,获取前一个元素、记录当前位置和判断迭代是否已结束。
21
22 //2.声明集合接口并描述一个获取迭代器的方法。 其返回值必须是迭代器接口。
23 //如果你计划拥有多组不同的迭代器, 则可以声明多个类似的方法。
24
25 //3.为希望使用迭代器进行遍历的集合实现具体迭代器类。
26 //迭代器对象必须与单个集合实体链接,通常将聚合对象作为迭代器的构造函数参数传入的方式来建立。
27
28 //4.在你的集合类中实现集合接口。其主要思想是针对特定集合为客户端代码提供创建迭代器的快捷方式。
29 //其中集合对象必须将自身传递给迭代器的构造函数来创建两者之间的链接。
30
31 //5.检查客户端代码, 使用迭代器替代所有集合遍历代码。
32 //每当客户端需要遍历集合元素时都会获取一个新的迭代器。
33 //
34
35 #endregion
36
37 //集合 (Collection) 接口声明一个或多个方法来获取与集合兼容的迭代器。
38 //返回方法的类型必须被声明为迭代器接口, 因此具体集合可以返回各种不同种类的迭代器。
39 public interface IteratorPattern<T>
40 {
41 Iterator<T> GetIterator();
42 }
43
44 //迭代器 (Iterator) 接口声明了遍历集合所需的操作: 获取下一个元素、 获取当前位置和重新开始迭代等。
45 public abstract class Iterator<T>
46 {
47 public abstract T Current { get; }
48 public abstract bool MoveNext();
49 public abstract void Reset();
50 public abstract int GetIndex();
51 }
52
53 //具体集合 (Concrete Collections) 会在客户端请求迭代器时返回一个特定的具体迭代器类实体。
54 public class ConcreteIteratorPattern<T> : IteratorPattern<T>
55 {
56 List<T> _objList = new List<T>();
57 public ConcreteIteratorPattern(T[] objs)
58 {
59 _objList.AddRange(objs);
60 }
61
62 public Iterator<T> GetIterator()
63 {
64 return new ConcreteIterator<T>(_objList);
65 }
66 }
67
68 //具体迭代器 (Concrete Iterators) 实现遍历集合的一种特定算法。
69 //迭代器对象必须跟踪自身遍历的进度。 这使得多个迭代器可以相互独立地遍历同一集合。
70 public class ConcreteIterator<T> : Iterator<T>
71 {
72 private List<T> _objList;
73 private int _index = -1;
74
75 public ConcreteIterator(List<T> objList)
76 {
77 this._objList = objList;
78 }
79
80 public override T Current => GetCurrent();
81 private T GetCurrent()
82 {
83 return _objList[_index];
84 }
85
86 public override int GetIndex()
87 {
88 return _index;
89 }
90
91 public override bool MoveNext()
92 {
93 _index++;
94 if (_index < _objList.Count())
95 {
96 return true;
97 }
98
99 return false;
100 }
101
102 public override void Reset()
103 {
104 _index = 0;
105 }
106 }
107
108 //客户端 (Client) 通过集合和迭代器的接口与两者进行交互。
109 //这样一来客户端无需与具体类进行耦合, 允许同一客户端代码使用各种不同的集合和迭代器。
110 //客户端通常不会自行创建迭代器, 而是会从集合中获取。但当客户端需要自定义特殊迭代器时例外。
111 public class IteratorPatternClient
112 {
113 public static void Test()
114 {
115 int[] arr = new int[] { 2, 5, 6, 8, 9 };
116 IteratorPattern<int> iteratorPattern = new ConcreteIteratorPattern<int>(arr);
117 Iterator<int> iterator = iteratorPattern.GetIterator();
118
119 while (iterator.MoveNext())
120 {
121 Console.WriteLine($"current = {iterator.Current},index = {iterator.GetIndex()}");
122 }
123 }
124 }
125 }