深入理解Java設計模式之迭代器模式

一、什麼是迭代器模式

迭代器模式是針對集合對象而生的,對於集合對象而言,肯定會涉及到對集合的添加和刪除操作,同時也肯定支持遍歷集合元素的操作,我們此時可以把遍歷操作放在集合對象中,但這樣的話,集合對象既承擔太多的責任瞭,面向對象設計原則中有一條就是單一職責原則,所有我們要盡可能地分離這些職責,用不同的類取承擔不同的責任,迭代器模式就是用迭代器類來承擔遍歷集合的職責。

定義:迭代器模式提供瞭一種方法順序訪問一個聚合對象中的各個元素,而又無需暴露該對象的內部實現,這樣既可以做到不暴露集合的內部結構,又可讓外部代碼透明地訪問集合內部的數據

二、迭代器模式的結構

抽象容器角色(Aggregate):負責提供創建具體迭代器角色的接口,一般是一個接口,提供一個iterator()方法,例如java中的Collection接口,List接口,Set接口等。

具體容器角色(ConcreteAggregate):就是實現抽象容器的具體實現類,比如List接口的有序列表實現ArrayList,List接口的鏈表實現LinkedList,Set接口的哈希列表的實現HashSet等。

抽象迭代器角色(Iterator):負責定義訪問和遍歷元素的接口。

具體迭代器角色(ConcreteIterator):實現迭代器接口,並要記錄遍歷中的當前位置。

三、迭代器模式的使用場景

訪問一個集合對象的內容而無需暴露它的內部表示

為遍歷不同的集合結構提供一個統一的接口

四、迭代器模式的優缺點

優點:

迭代器模式使得訪問一個聚合對象的內容而無需暴露它的內部表示,即迭代抽象。

迭代器模式為遍歷不同的集合結構提供瞭一個統一的接口,從而支持同樣的算法在不同的集合結構上進行操作

缺點:

迭代器模式在遍歷的同時更改迭代器所在的集合結構會導致出現異常。所以使用foreach語句隻能在對集合進行遍歷,不能在遍歷的同時更改集合中的元素。

五、迭代器模式的實現

抽象聚合類

public interface IListCollection
{
    Iterator GetIterator();
}

迭代器抽象類

public interface Iterator
{
    bool MoveNext();
    Object GetCurrent();
    void Next();
    void Reset();
}

具體聚合類

public class ConcreteList : IListCollection
{
    int[] collection;
    public ConcreteList()
    {
        collection = new int[] { 2, 4, 6, 8 };
    }
    public Iterator GetIterator()
    {
        return new ConcreteIterator(this);
    }
    public int Length
    {
        get { return collection.Length; }
    }
    public int GetElement(int index)
    {
        return collection[index];
    }
}

具體迭代器類

public class ConcreteIterator : Iterator
{
    // 迭代器要集合對象進行遍歷操作,自然就需要引用集合對象
    private ConcreteList _list;
    private int _index;
    public ConcreteIterator(ConcreteList list)
    {
        _list = list;
        _index = 0;
    }
    public bool MoveNext()
    {
        if (_index < _list.Length)
        {
            return true;
        }
        return false;
    }
    public Object GetCurrent()
    {
        return _list.GetElement(_index);
    }
    public void Reset()
    {
        _index = 0;
    }
    public void Next()
    {
        if (_index < _list.Length)
        {
        _    index++;
        }
    }
}

客戶端調用

class Program
{
    static void Main(string[] args)
    {
        Iterator iterator;
        IListCollection list = new ConcreteList();
        iterator = list.GetIterator();
        while (iterator.MoveNext())
        {
            int i = (int)iterator.GetCurrent();
            Console.WriteLine(i.ToString());
            iterator.Next();
        }
        Console.Read();
    }
}

結果

六、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等類型

七、總結

迭代器模式就是抽象一個迭代器類來分離瞭集合對象的遍歷行為,這樣既可以做到不暴露集合的內部結構,又可讓外部代碼透明地訪問集合內部的數據

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: