C# 设计模式-迭代模式

一.介绍  

  迭代模式(Iterator Pattern)。属于行为型模式。它提供一种方法顺序访问聚合对象中各个元素,而又不暴露该对象的内部表示。

二.实现

  迭代模式是针对聚合对象使用的,一般使用聚合,有增删改操作,也需要进行遍历操作。如果聚合对象全实现这些功能,那根据单一职责原则,聚合对象就承担了太多责任。迭代模式就是去实现遍历聚合对象责任的方式,通俗理解,就是建立一个迭代类,这个包含了整个聚合对象,由这个迭代类记录当前聚合的当前位置以及去遍历查询这个聚合。下面实现的是标准的迭代器模式。

//抽象迭代器类
public abstract class Iterator
{
    public abstract object First();
    public abstract object Next();
    public abstract bool IsEnd();
    public abstract object CurrentItem();
}

//具体迭代器类
public class ConcreteIterator : Iterator
{
    ConcreteAggregate list;
    int position = -1;
    public ConcreteIterator(ConcreteAggregate aggregate)
    {
        this.list = aggregate;
        position = 0;
    }

    public override object CurrentItem()
    {
        if (position >= 0 && position < list.Count)
        {
            return list[position];
        }
        throw new IndexOutOfRangeException();
    }

    public override object First()
    {
        return list[0];
    }

    public override bool IsEnd()
    {
        return position >= list.Count - 1;
    }

    public override object Next()
    {
        ++position;
        if (position < list.Count)
        {
            return list[position];
        }
        throw new IndexOutOfRangeException();
    }
}

//抽象聚合类
public abstract class Aggregate
{
    public abstract Iterator GetIterator();
}

//具体聚合类
public class ConcreteAggregate : Aggregate
{
    List<int> _items = new List<int>();

    public ConcreteAggregate()
    {

    }

    public override Iterator GetIterator()
    {
        return new ConcreteIterator(this);
    }

    public int Count
    {
        get
        {
            return _items.Count();
        }
    }

    public int this[int index]
    {
        get
        {
            return _items[index];
        }
        set
        {
            _items.Add(value);
        }
    }
}

//调用
public static void Main(string[] args)
{
    var arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    var aggregate = new ConcreteAggregate();
    int index = 0;
    foreach (var i in arr)
    {
        aggregate[index] = i;
        index++;
    }


    var iterator = aggregate.GetIterator();

    Console.WriteLine(iterator.First());
    while (!iterator.IsEnd())
    {
        var i = iterator.Next();
        Console.WriteLine(i);
    }
}

 

  在C#中,迭代模式的聚合接口和迭代器接口都已经存在,其中IEnumerator接口是迭代器角色,IEnumberable接口是抽象聚合角色。

public class Person : IEnumerable<string>
{
    string[] persons;
    public Person(string[] persons)
    {
        this.persons = persons;
    }

    public IEnumerator<string> GetEnumerator()
    {
        return new PersonIEnumerator(persons);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return new PersonIEnumerator(persons);
    }
}

public class PersonIEnumerator : IEnumerator<string>
{
    private int position = -1;
    private string[] items;

    public PersonIEnumerator(string[] items)
    {
        this.items = items;
    }

    public string Current
    {
        get
        {
            return items[position];
        }
    }

    object IEnumerator.Current => Current;

    public void Dispose()
    {
    }

    public bool MoveNext()
    {
        ++position;
        return position < items.Length;
    }

    public void Reset()
    {
        position = -1;
    }
}

//调用
public static void Main(string[] args)
{
    Person person = new Person(new string[] { "", "", "", "" });
    Console.WriteLine("foreach demo:");
    foreach (var p in person)
    {
        Console.WriteLine(p);
    }
    Console.WriteLine();


    var ienumerator = person.GetEnumerator();
    Console.WriteLine("MoveNext demo:");
    while (ienumerator.MoveNext())
    {
        Console.WriteLine(ienumerator.Current);
    }
}

三.总结

  优点:

  1.迭代模式使得访问一个聚合对象的内容而不用暴露它的内部表示,即迭代抽象。

  2.迭代模式为遍历不同的聚合结构提供了一个统一的接口,从而支持了不同聚合结构可以使用同样的算法。

  缺点:

  1.迭代模式使得在遍历时更改聚合对象会出现异常,所以使用foreach语句只能进行遍历,不能在遍历时进行修改聚合中元素操作。

 

posted @ 2021-01-28 14:04  shine声  阅读(230)  评论(0编辑  收藏  举报