設計模式筆記(18)—迭代器模式(行為型)

來源:互聯網
上載者:User
文章目錄
  • Gof定義
  • 動機
  • Iterator模式的幾個要點
Gof定義

提供一種方法順序訪問一個彙總對象中的各個元素, 而又不暴露該對象的內部表示。

動機

在軟體構建過程中,集合對象內部結構常常變化各異。但對於這些集合對象,我們希望在不暴露其內部結構的同時,可以讓外部客戶代碼透明地訪問其中包含的元素;同時這種“透明遍曆”也為“同一種演算法在多種集合對象上進行操作”提供了可能。使用物件導向技術將這種遍曆機制抽象為“迭代器對象”為“應對變化中的集合對象”提供了一種優雅的方式。

迭代器模式結構圖:

Aggregate:集合結構介面

Iterator:迭代器介面

Concreteaggregate:集合結構的具體類,繼承Aggregate介面

ConcreteIteator:具體的迭代器類

代碼實現:

/// <summary>/// 集合結構介面/// </summary>public interface Aggregate{    Iterator CreateIterator();}/// <summary>/// 迭代器介面/// </summary>public interface Iterator{    object First();    object Next();    bool IsDone();    object CurrentItem();}/// <summary>/// 集合結構的具體類/// </summary>class ConcreteAggregate : Aggregate{    private List<object> items = new List<object>();    public 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); }    }}/// <summary>/// 具體的迭代器類/// </summary>class ConcreteIterator : Iterator{    private ConcreteAggregate _aggregate;    private int _current = 0;    public ConcreteIterator(ConcreteAggregate aggregate)    {        this._aggregate = aggregate;    }    public object First()    {        return _aggregate[0];    }    public object Next()    {        object r = null;        _current++;        if (_current < _aggregate.Count)        {            r = _aggregate[_current];        }        return r;    }    public bool IsDone()    {        return _current >= _aggregate.Count ? true : false;    }    public object CurrentItem()    {        return _aggregate[_current];    }}/// <summary>/// 用戶端調用/// </summary>class Program{    static void Main(string[] args)    {        ConcreteAggregate ca = new ConcreteAggregate();        ca[0] = "AspNet3.5 揭秘";        ca[0] = "重構:改善既有代碼的設計";        ca[2] = "設計模式";        ca[3] = "人月神話";        ca[4] = "代碼大全2";        Iterator i = new ConcreteIterator(ca);        while (!i.IsDone())        {            Console.WriteLine("要讀的書:" + i.CurrentItem());            i.Next();        }    }}

上面的代碼是根據結構圖實現的基礎代碼,在設計的運用中可以使用Net架構給我們提供的相關介面IEnumerable和IEnumerator,這兩個介面在Net中的實現代碼如下:

public interface IEnumerable{    IEmumerator GetEnumerator();}public interface IEmumerator{    Object Current { get; }    bool MoveNext();    void Reset();}

在Net中List實現了IEnumerable介面,下面的代碼將List作為資料的容器來實現遍曆:

class Program{    static void Main(string[] args)    {        List<string> list = new List<string>         {             "AspNet3.5 揭秘","重構:改善既有代碼的設計","設計模式",            "人月神話","代碼大全2"        };        IEnumerator i = list.GetEnumerator();        while (i.MoveNext())        {            Console.WriteLine("要讀的書:" + i.Current);        }    }}

上面的代碼中試調用List的GetEnumerator方法返回IEmumerator類型的集合,然後取遍曆,這樣仍然顯得比較麻煩,其實在Net中foreach已經實現了這樣的功能,代碼如下:

class Program{    static void Main(string[] args)    {        List<string> list = new List<string>         {             "AspNet3.5 揭秘","重構:改善既有代碼的設計","設計模式",            "人月神話","代碼大全2"        };        foreach (string s in list)        {            Console.WriteLine("要讀的書:" + s);        }    }}

可以看出foreach其實就是實現了下面這段代碼

IEnumerator i = list.GetEnumerator();while (i.MoveNext()){    Console.WriteLine("要讀的書:" + i.Current);}
Iterator模式的幾個要點
  • 迭代抽象:訪問一個彙總對象的內容而無需暴露它的內部表示。
    迭代多態:為遍曆不同的集合結構提供一個統一的介面,從而支援同樣的演算法在不同的集合結構上進行操作。

    迭代器的健壯性考慮:遍曆的同時更改迭代器所在的集合結構,會導致問題。

返回開篇(索引)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.