c#设计模式系列:迭代器模式(Iterator)

2021-07-13 09:09

阅读:416

  • 迭代器模式的定义

  迭代器模式提供了一种方法顺序访问一个聚合对象中的各个元素,而又无需暴露该对象的内部实现,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据

  • 迭代器模式的结构图

技术分享图片

  • 迭代器模式的组成
  1.    迭代器角色(Iterator):迭代器角色负责定义访问和遍历的接口
  2. 具体迭代器角色(Concrete Iterator):具体迭代器角色实现了迭代器接口,并需要记录遍历中的当前位置。
  3. 聚合角色(Aggregate):聚合角色负责定义获得迭代器角色的接口
  4. 具体聚合角色(ConcreteAggregate):具体聚合角色实现聚合角色接口

迭代器代码实现

技术分享图片技术分享图片
  class Program
    {
        static void Main(string[] args)
        {
            ConcreteAggregate a = new ConcreteAggregate();
            a[0] = "a";
            a[1] = "b";
            a[2] = "c";
            a[3] = "d";
            a[4] = "e";
            a[5] = "f";
            a[6] = "g";

            Iterator i = new ConcreteIterator(a);
            object item = i.First();
            while (!i.IsDone())
            {
                Console.WriteLine(i.CurrentItem());
                i.Next();
            }

        }
    }
    /// 迭代器接口
    /// 
   public abstract class Iterator
    {
        public abstract object First();
        public abstract object Next();
        public abstract bool IsDone();
        public abstract object CurrentItem();
    }

    //聚集抽象类
    public abstract class Aggregate
    {
        public abstract Iterator CreateIterator();
    }

    /// 
    /// 具体抽象类
    /// 
    public class ConcreteAggregate : Aggregate
    {
        private IListobject> items = new Listobject>();
        public override Iterator CreateIterator()
        {
            return new ConcreteIterator(this);
        }

        public int Count
        {
            get { return items.Count; }
        }

        public object this[int index] {
            get { return items[index]; }
            set { items.Insert(index, value); }
        }
    }


    public class ConcreteIterator : Iterator
    {
        private ConcreteAggregate aggregate;
        private int current = 0;
        public ConcreteIterator(ConcreteAggregate aggregate)
        {
            this.aggregate = aggregate;
        }

        public override object First()
        {
            return aggregate[0];
        }
        public override object Next()
        {
            object ret = null;
            current++;
            if (currentreturn ret;
        }

        public override bool IsDone()
        {
            return current >= aggregate.Count ? true : false;
        }

        public override object CurrentItem()
        {
            return aggregate[current];
        }
    }
View Code

NET中迭代器模式的应用

在mscorlib程序集里有这样一个命名空间,该命名空间就是:System.Collections,在该命名空间里面早已有了迭代器模式的实现。对于聚集接口和迭代器接口已经存在了,其中IEnumerator扮演的就是迭代器的角色,它的实现如下:

public interface IEnumerator
 {
      object Current
      {
           get;
      }

     bool MoveNext();

     void Reset();
 }

属性Current返回当前集合中的元素,Reset()方法恢复初始化指向的位置,MoveNext()方法返回值true表示迭代器成功前进到集合中的下一个元素,返回值false表示已经位于集合的末尾。能够提供元素遍历的集合对象,在.Net中都实现了IEnumerator接口。
IEnumerable则扮演的就是抽象聚集的角色,只有一个GetEnumerator()方法,如果集合对象需要具备跌代遍历的功能,就必须实现该接口。

public interface IEnumerable
{
    IEumerator GetEnumerator();
}

抽象聚合角色(Aggregate)和抽象迭代器角色(Iterator)分别是IEnumerable接口和IEnumerator接口,具体聚合角色(ConcreteAggregate)有Queue类型, BitArray等类型

迭代器模式的优缺点

由于迭代器承担了遍历集合的职责,从而有以下的优点:

  • 迭代器模式使得访问一个聚合对象的内容而无需暴露它的内部表示,即迭代抽象。
  • 迭代器模式为遍历不同的集合结构提供了一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作

迭代器模式存在的缺陷:

  • 迭代器模式在遍历的同时更改迭代器所在的集合结构会导致出现异常。所以使用foreach语句只能在对集合进行遍历,不能在遍历的同时更改集合中的元素。

总结

迭代器模式就是抽象一个迭代器类来分离了集合对象的遍历行为,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据


      今天看到了一句话觉得很有道理,再此分享给大家 --我们今天的生活是由三五年前选择决定的,而三五年后的生活是由今天决定的!晚安


评论


亲,登录后才可以留言!