设计模式之迭代器模式
迭代器模式 Iterator
Intro
迭代器模式,提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
迭代器模式是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据。
使用场景
当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式。
当你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。
实现方式
如果要自己实现需要有下面几个类:
一个迭代器抽象类(或接口)
一个聚集抽象类(或接口)
具体实现的迭代器类
具体实现的聚集类
Sample
public abstract class Iterator
{
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}
public class ConcreteIterator : Iterator
{
private readonly ConcreteAggregate _aggregate;
private int _current = 0;
public ConcreteIterator(ConcreteAggregate aggregate) => _aggregate = aggregate;
public override object First()
{
return _aggregate[0];
}
public override object Next()
{
_current++;
return _current >= _aggregate.TotalCount ? null : _aggregate[_current];
}
public override bool IsDone() => _current >= _aggregate.TotalCount;
public override object CurrentItem() => _aggregate[_current];
}
public abstract class Aggregate
{
///
/// 创建迭代器
///
///
public abstract Iterator CreateIterator();
}
public class ConcreteAggregate : Aggregate
{
private readonly IList
More
需要注意的是,使用迭代器模式遍历集合时,不要对集合进行增加元素或者删除元素操作
在 C# 中实现 IEnumerable 接口就可以比较方便的实现一个迭代器,foreach 就是迭代器的一个语法糖
来看一下 IEnumerabe 的定义:
// 聚集抽象
public interface IEnumerable
{
/// Returns an enumerator that iterates through a collection.
/// An object that can be used to iterate through the collection.
IEnumerator GetEnumerator();
}
// 迭代器抽象
public interface IEnumerator
{
/// Advances the enumerator to the next element of the collection.
///
/// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection.
/// The collection was modified after the enumerator was created.
bool MoveNext();
/// Gets the element in the collection at the current position of the enumerator.
/// The element in the collection at the current position of the enumerator.
object Current { get; }
/// Sets the enumerator to its initial position, which is before the first element in the collection.
/// The collection was modified after the enumerator was created.
void Reset();
}
最后留个思考题给你,List 在 foreach 的时候如果删除一个元素会发生什么?内部是怎么样实现的呢? 可以自己实践一下
Reference
- https://github.com/WeihanLi/DesignPatterns/tree/master/BehaviorPattern/IteratorPattern