65.9K
CodeProject 正在变化。 阅读更多。
Home

迭代器模式

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2008年10月2日

CPOL

2分钟阅读

viewsIcon

11269

迭代器模式的作用是提供一种按顺序访问聚合对象的方式,而无需了解聚合对象的内部结构。

迭代器模式的作用是提供一种访问聚合
对象的方式,按顺序进行,而无需了解其内部
结构。 该模式在 C# 中被广泛使用,在 .NET 框架中,我们
拥有 IEnumerator 和 IEnumerable 接口来帮助我们
为聚合对象实现迭代器。 当您实现自己的
聚合对象时,应该实现这些接口,以暴露一种
遍历聚合对象的方式。

迭代器模式的应用场景 
您应该在以下情况下使用该模式

  • 您需要一个统一的接口来遍历不同的聚合
    结构。
  • 您有多种遍历聚合结构的方式。
  • 您不希望暴露聚合对象的内部
    表示。

UML 图
Iterator UML

C# 示例

#region Aggregate Item

class AggregateItem
{
    #region Properties

    /// <summary>
    /// The AggregateItem's data
    /// </summary>
    public string Data { get; set; }

    #endregion



    #region Ctor

    /// <summary>
    /// Construct a new AggregateItem with
    /// the given data
    /// </summary>
    /// <param name="data">The given data</param>
    public AggregateItem(string data)
    {
        Data = data;
    }

    #endregion
}

#endregion

#region Aggregate Object

interface Aggregate
{
    Iterator GetIterator();
}

class AggregateImpl : Aggregate
{
    #region Members

    private readonly List<AggregateItem> _aggregate;

    #endregion

    #region Properties

    /// <summary>
    /// The number of items in the
    /// aggregate
    /// </summary>
    public int Count
    {
        get
        {
            return _aggregate.Count;
        }
    }

    /// <summary>
    /// The indexer for the aggregate
    /// </summary>
    public AggregateItem this[int index]
    {
        get
        {
            return _aggregate[index];
        }
        set
        {
            _aggregate[index] = value;
        }
    }
    #endregion

    #region Ctor

    /// <summary>
    /// Construct a new AggregateImpl
    /// </summary>
    public AggregateImpl()
    {
        _aggregate = new List<AggregateItem>();
    }
    #endregion

    #region Aggregate Members

    /// <summary>
    /// Returns the Iterator for this aggregate
    /// object.
    /// </summary>
    /// <returns>Iterator</returns>
    public Iterator GetIterator()
    {
        return new IteratorImpl(this);
    }
    #endregion
}
#endregion

#region Iterator

interface Iterator
{
    object First();
    object Next();
    bool IsDone();
    object Current();
}

class IteratorImpl : Iterator
{

    #region Memebrs

    private readonly AggregateImpl _aggregate;
    private int _nCurrentIndex;

    #endregion

    #region Iterator Members

    /// <summary>
    /// Return the first object of the iterator.
    /// </summary>
    /// <returns>First object of the iterator</returns>
    public object First()
    {
        return _aggregate[0];
    }

    /// <summary>
    /// Return the current object in the iterator and
    /// advance to the next one.
    /// </summary>
    /// <returns>The next object in the iterator</returns>
    public object Next()
    {
        object result = null;
        if (_nCurrentIndex < _aggregate.Count - 1)
        {
            result = _aggregate[_nCurrentIndex];
            _nCurrentIndex++;
        }
        return result;
    }

    /// <summary>
    /// Returns true if the iteration is done.
    /// </summary>
    /// <returns>True if the iteration is done</returns>
    public bool IsDone()
    {
        return _nCurrentIndex >= _aggregate.Count;
    }

    /// <summary>
    /// Return the current object in the iterator.
    /// </summary>
    /// <returns></returns>
    public object Current()
    {
        return _aggregate[_nCurrentIndex];
    }

    #endregion

    #region Ctor

    /// <summary>
    /// Construct a new IteratorImpl with the given
    /// aggregate.
    /// </summary>
    /// <param name="aggregate">The given aggregate</param>
    public IteratorImpl(AggregateImpl aggregate)
    {
        _nCurrentIndex = 0;
        _aggregate = aggregate;
    }

    #endregion
}

#endregion

示例中包含 5 名玩家。 第一名玩家是一个聚合
项,它是一个简单的数据结构。 我们还有一个聚合
接口,它具有一个 GetIterator 方法,该方法返回迭代器。
有一个迭代器接口,它规定了迭代器的
行为规范。 我使用了这两个接口来实现一个
聚合对象和一个迭代器。

IEnumerator 和 IEnumerable 接口
IEnumerator 和 IEnumerable 是在 C# 中实现
迭代器模式的方式。 IEnumerable 接口暴露了
枚举器,它支持对非泛型或
泛型集合进行简单的迭代。 它用于集合本身,以暴露枚举器的功能
。 IEnumerable 在 LINQ 中被广泛使用,
它是暴露 LINQ 功能的基础。 IEnumerator
接口支持对非泛型或泛型集合进行简单的迭代。
枚举器是一种只读方式来遍历集合。
您应该使用这些接口来在 C# 中实现迭代器模式
。 它们的实现方式与我之前提供的迭代器模式实现
方式类似。

简单的遍历示例 尽管使用 foreach 循环更可取,但您
可以使用 IEnumerator 接口遍历集合
,如以下示例所示

// build a new string list
var strList = new List<string>
                  {
                      "str1",
                      "str2",
                      "str3"
                  };


// get list enumerator
IEnumerator<string> enumerator = strList.GetEnumerator();


// use the enumerator to traverse the list
// and output the list's items to console
string str;
while (enumerator.MoveNext())
{
    str = enumerator.Current;
    if (!string.IsNullOrEmpty(str))
    {
        Console.WriteLine("{0}", str);
    }
}

摘要

总而言之,我们广泛使用迭代器模式,即使
我们不知道它。 每当您运行 foreach 循环时,迭代器
模式会在底层使用。 LINQ 扩展是基于 IEnumerable 接口构建的
,它是 .Net 框架中迭代器模式实现的一部分

© . All rights reserved.