迭代器模式(Iterator Pattern)
迭代器模式将集合对象的遍历操作从集合类中拆分出来,放到迭代器类中,让两者的职责更加单一。集合对象也可以叫容器、聚合对象。
结构图:
角色:
- 迭代器(Iterator):声明遍历集合所需的一系列操作。
- 具体迭代器(Concrete Iterators):实现迭代器申明的所有接口。
- 集合(Collection):声明一个或多个方法来获取与集合兼容的迭代器。
- 具体集合(Concrete Collections):实现集合接口,返回一个具体的迭代器对象。
适用场景:
- 访问集合需要屏蔽内部时间。
- 为一个集合提供多种遍历方式。
优点:
- 对使用者屏蔽了复杂的数据结构。
- 对遍历操作封装到了单独的类中,使集合和迭代器职责更加单一。
- 可以轻易替换遍历代码,更加符合开闭原则。
优点:
- 迭代算法可能过于复杂,优先使用开发语言提供的方式可能会更好。
代码(C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
public interface ITerator<T> { bool HasNext(); void Next(); T CurrentItem(); }
public class ListIterator<T> : ITerator<T> { private int _cursor; private List<T> _list;
public ListIterator(List<T> list) { _list = list; }
public bool HasNext() { return _cursor != _list.Count; }
public void Next() { _cursor++; }
public T CurrentItem() { if (_cursor >= _list.Count) throw new NullReferenceException();
return _list[_cursor]; } }
public interface IAggregate<T> { ITerator<T> CreateIterator(); }
public class ConcreteList<T> : IAggregate<T> { private readonly List<T> _collection;
public ConcreteList() { _collection = new List<T>(); }
public void AddItem(T item) { _collection.Add(item); }
public ITerator<T> CreateIterator() { return new ListIterator<T>(_collection); } }
ConcreteList<int> concreteList = new ConcreteList<int>(); concreteList.AddItem(1); concreteList.AddItem(2); concreteList.AddItem(3); concreteList.AddItem(4);
ITerator<int> iterator = concreteList.CreateIterator();
while (iterator.HasNext()) { Console.WriteLine(iterator.CurrentItem()); iterator.Next(); }
|
最后
在大部分语言语言中都可以通过for、foreach来遍历集合,foreach的本质其实就是迭代器模式。在遍历的过程中,通常是不允许修改集合中的元素,增加或者删除集合中的元素,有可能会导致某个元素被重复遍历或遍历不到,这种行为称为结果不可预期行为或者未决行为。