天天看點

.NET設計模式-疊代器模式(Iterator Pattern)

概述

在面向對象的軟體設計中,我們經常會遇到一類集合對象,這類集合對象的内部結構可能有着各種各樣的實作,但是歸結起來,無非有兩點是需要我們去關心的:一是集合内部的資料存儲結構,二是周遊集合内部的資料。面向對象設計原則中有一條是類的單一職責原則,是以我們要盡可能的去分解這些職責,用不同的類去承擔不同的職責。Iterator模式就是分離了集合對象的周遊行為,抽象出一個疊代器類來負責,這樣既可以做到不暴露集合的内部結構,又可讓外部代碼透明的通路集合内部的資料。

意圖

提供一種方法順序通路一個聚合對象中各個元素, 而又不需暴露該對象的内部表示。[GOF 《設計模式》]

結構圖

Iterator模式結構圖如下:

.NET設計模式-疊代器模式(Iterator Pattern)

圖1  Iterator模式結構圖

生活中的例子

疊代器提供一種方法順序通路一個集合對象中各個元素,而又不需要暴露該對象的内部表示。在早期的電視機中,一個撥盤用來改變頻道。當改變頻道時,需要手工轉動撥盤移過每一個頻道,而不論這個頻道是否有信号。現在的電視機,使用[後一個]和[前一個]按鈕。當按下[後一個]按鈕時,将切換到下一個預置的頻道。想象一下在陌生的城市中的旅店中看電視。當改變頻道時,重要的不是幾頻道,而是節目内容。如果對一個頻道的節目不感興趣,那麼可以換下一個頻道,而不需要知道它是幾頻道。

.NET設計模式-疊代器模式(Iterator Pattern)

圖2  使用選頻器做例子的Iterator模式對象圖

Iterator模式解說

在面向對象的軟體設計中,我們經常會遇到一類集合對象,這類集合對象的内部結構可能有着各種各樣的實作,但是歸結起來,無非有兩點是需要我們去關心的:一是集合内部的資料存儲結構,二是周遊集合内部的資料。面向對象設計原則中有一條是類的單一職責原則,是以我們要盡可能的去分解這些職責,用不同的類去承擔不同的職責。Iterator模式就是分離了集合對象的周遊行為,抽象出一個疊代器類來負責,這樣既可以做到不暴露集合的内部結構,又可讓外部代碼透明的通路集合内部的資料。下面看一個簡單的示意性例子,類結構圖如下:

.NET設計模式-疊代器模式(Iterator Pattern)

圖3 示例代碼結構圖

首先有一個抽象的聚集,所謂的聚集就是就是資料的集合,可以循環去通路它。它隻有一個方法GetIterator()讓子類去實作,用來獲得一個疊代器對象。

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

/// <summary>

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

/// 抽象聚集

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

/// </summary>

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

public interface IList

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

{

.NET設計模式-疊代器模式(Iterator Pattern)

    IIterator GetIterator();

.NET設計模式-疊代器模式(Iterator Pattern)

}

抽象的疊代器,它是用來通路聚集的類,封裝了一些方法,用來把聚集中的資料按順序讀取出來。通常會有MoveNext()、CurrentItem()、Fisrt()、Next()等幾個方法讓子類去實作。

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

/// 抽象疊代器

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

public interface IIterator

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    bool MoveNext();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    Object CurrentItem();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    void First();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    void Next();

.NET設計模式-疊代器模式(Iterator Pattern)

具體的聚集,它實作了抽象聚集中的唯一的方法,同時在裡面儲存了一組資料,這裡我們加上Length屬性和GetElement()方法是為了便于通路聚集中的資料。

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

/// 具體聚集

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

public class ConcreteList : IList

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    int[] list;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public ConcreteList()

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    {

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        list = new int[] { 1,2,3,4,5};

.NET設計模式-疊代器模式(Iterator Pattern)

    }

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public IIterator GetIterator()

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        return new ConcreteIterator(this);

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public int Length

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        get { return list.Length; }

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public int GetElement(int index)

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        return list[index];

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

具體疊代器,實作了抽象疊代器中的四個方法,在它的構造函數中需要接受一個具體聚集類型的參數,在這裡面我們可以根據實際的情況去編寫不同的疊代方式。

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

/// 具體疊代器

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

public class ConcreteIterator : IIterator

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    private ConcreteList list;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    private int index;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public ConcreteIterator(ConcreteList list)

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        this.list = list;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        index = 0;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public bool MoveNext()

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        if (index < list.Length)

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

            return true;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        else

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

            return false;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public Object CurrentItem()

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        return list.GetElement(index) ;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public void First()

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public void Next()

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        {

.NET設計模式-疊代器模式(Iterator Pattern)

            index++;

.NET設計模式-疊代器模式(Iterator Pattern)

        }

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

簡單的用戶端程式調用:

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

/// 用戶端程式

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

class Program

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    static void Main(string[] args)

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        IIterator iterator;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        IList list = new ConcreteList();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        iterator = list.GetIterator();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        while (iterator.MoveNext())

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

            int i = (int)iterator.CurrentItem();

.NET設計模式-疊代器模式(Iterator Pattern)

            Console.WriteLine(i.ToString());

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

            iterator.Next();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        Console.Read();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

一個簡單的疊代器示例就結束了,這裡我們并沒有利用任何的.NET特性,在C#中,實作Iterator模式已經不需要這麼麻煩了,已經C#語言本身就有一些特定的實作,下面會說到。

.NET中的Iterator模式

在.NET下實作Iterator模式,對于聚集接口和疊代器接口已經存在了,其中IEnumerator扮演的就是疊代器的角色,它的實作如下:

.NET設計模式-疊代器模式(Iterator Pattern)

public interface IEumerator

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    object Current

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        get;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    void Reset();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

屬性Current傳回目前集合中的元素,Reset()方法恢複初始化指向的位置,MoveNext()方法傳回值true表示疊代器成功前進到集合中的下一個元素,傳回值false表示已經位于集合的末尾。能夠提供元素周遊的集合對象,在.Net中都實作了IEnumerator接口。

IEnumerable則扮演的就是抽象聚集的角色,隻有一個GetEnumerator()方法,如果集合對象需要具備跌代周遊的功能,就必須實作該接口。

.NET設計模式-疊代器模式(Iterator Pattern)

public interface IEnumerable

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    IEumerator GetEnumerator();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

public class Persons : IEnumerable 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

.NET設計模式-疊代器模式(Iterator Pattern)

    public string[] m_Names; 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public Persons(params string[] Names) 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    { 

.NET設計模式-疊代器模式(Iterator Pattern)

        m_Names = new string[Names.Length]; 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        Names.CopyTo(m_Names,0); 

.NET設計模式-疊代器模式(Iterator Pattern)

    } 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    private string this[int index] 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        get 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        { 

.NET設計模式-疊代器模式(Iterator Pattern)

            return m_Names[index]; 

.NET設計模式-疊代器模式(Iterator Pattern)

        } 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        set 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

            m_Names[index] = value; 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public IEnumerator GetEnumerator()

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        return new PersonsEnumerator(this);

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

public class PersonsEnumerator : IEnumerator

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    private int index = -1;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    private Persons P;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public PersonsEnumerator(Persons P)

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        this.P = P;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        index++;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        return index < P.m_Names.Length;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public void Reset()

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        index = -1;

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public object Current

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        get

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

            return P.m_Names[index];

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

來看用戶端代碼的調用:

.NET設計模式-疊代器模式(Iterator Pattern)

class Program 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    static void Main(string[] args) 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        Persons arrPersons = new Persons("Michel","Christine","Mathieu","Julien"); 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        foreach (string s in arrPersons) 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

            Console.WriteLine(s); 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        Console.ReadLine(); 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

程式将輸出:

.NET設計模式-疊代器模式(Iterator Pattern)

Michel 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

Christine 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

Mathieu 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

Julien

現在我們分析編譯器在執行foreach語句時到底做了什麼,它執行的代碼大緻如下:

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

          Persons arrPersons = new Persons("Michel","Christine","Mathieu","Julien"); 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

          IEnumerator e = arrPersons.GetEnumerator(); 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

          while (e.MoveNext()) 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

          { 

.NET設計模式-疊代器模式(Iterator Pattern)

            Console.WriteLine((string)e.Current); 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

          }

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

          Console.ReadLine();

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

可以看到這段代碼跟我們最前面提到的示例代碼非常的相似。同時在這個例子中,我們把大部分的精力都花在了實作疊代器和可疊代的類上面,在.NET2.0下面,由于有了yield return關鍵字,實作起來将更加的簡單優雅。下面我們把剛才的例子在2.0下重新實作一遍:

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    string[] m_Names; 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

    public IEnumerator GetEnumerator() 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

        foreach (string s in m_Names) 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

            yield return s; 

.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)
.NET設計模式-疊代器模式(Iterator Pattern)

實作相同的功能,由于有了yield return關鍵字,變得非常的簡單。好了,關于.NET中的Iterator模式就說這麼多了,更詳細的内容大家可以參考相關的資料。

效果及實作要點

1.疊代抽象:通路一個聚合對象的内容而無需暴露它的内部表示。

2.疊代多态:為周遊不同的集合結構提供一個統一的接口,進而支援同樣的算法在不同的集合結構上進行操作。

3.疊代器的健壯性考慮:周遊的同時更改疊代器所在的集合結構,會導緻問題。

适用性

1.通路一個聚合對象的内容而無需暴露它的内部表示。

2.支援對聚合對象的多種周遊。

3.為周遊不同的聚合結構提供一個統一的接口(即, 支援多态疊代)。

總結

Iterator模式就是分離了集合對象的周遊行為,抽象出一個疊代器類來負責,這樣既可以做到不暴露集合的内部結構,又可讓外部代碼透明的通路集合内部的資料。

參考資料

Erich Gamma等,《設計模式:可複用面向對象軟體的基礎》,機械工業出版社

Robert C.Martin,《靈活軟體開發:原則、模式與實踐》,清華大學出版社

閻宏,《Java與模式》,電子工業出版社

Alan Shalloway James R. Trott,《Design Patterns Explained》,中國電力出版社

MSDN WebCast 《C#面向對象設計模式縱橫談(18):Iterator 疊代器模式(行為型模式)》

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。