深刻淺出設計模式——迭代器模式(Iterator Pattern)

模式動機

程序員

一個聚合對象,如一個列表(List)或者一個集合(Set),應該提供一種方法來讓別人能夠訪問它的元素,而又不須要暴露它的內部結構。
針對不一樣的須要,可能還要以不一樣的方式遍歷整個聚合對象,可是咱們並不但願在聚合對象的抽象層接口中充斥着各類不一樣遍歷的操做。
怎樣遍歷一個聚合對象,又不須要了解聚合對象的內部結構,還可以提供多種不一樣的遍歷方式,這就是迭代器模式所要解決的問題。
在迭代器模式中,提供一個外部的迭代器來對聚合對象進行訪問和遍歷,迭代器定義了一個訪問該聚合元素的接口,而且能夠跟蹤當前遍歷的元素,瞭解哪些元素已經遍歷過而哪些沒有。
有了迭代器模式,咱們會發現對一個複雜的聚合對象的操做會變得如此簡單。編程

模式定義
迭代器模式(Iterator Pattern) :提供一種方法來訪問聚合對象,而不用暴露這個對象的內部表示,其別名爲遊標(Cursor)。迭代器模式是一種對象行爲型模式。
Iterator Pattern: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
Frequency of use: high
UML圖

設計模式

模式結構
迭代器模式包含以下角色:
Iterator: 抽象迭代器
ConcreteIterator: 具體迭代器
Aggregate: 抽象聚合類
ConcreteAggregate: 具體聚合類數據結構

模式分析
聚合是一個管理和組織數據對象的數據結構。
聚合對象主要擁有兩個職責:一是存儲內部數據;二是遍歷內部數據。
存儲數據是聚合對象最基本的職責。
將遍歷聚合對象中數據的行爲提取出來,封裝到一個迭代器中,經過專門的迭代器來遍歷聚合對象的內部數據,這就是迭代器模式的本質。迭代器模式是「單一職責原則」的完美體現。架構

在迭代器模式中應用了工廠方法模式,聚合類充當工廠類,而迭代器充當產品類,因爲定義了抽象層,系統的擴展性很好,在客戶端能夠針對抽象聚合類和抽象迭代器進行編程。
因爲不少編程語言的類庫都已經實現了迭代器模式,所以在實際使用中咱們不多自定義迭代器,只須要直接使用Java、C#等語言中已定義好的迭代器便可,迭代器已經成爲咱們操做聚合對象的基本工具之一。編程語言

模式實例與解析
想走?能夠!先買票—迭代器模式示例
體系結構

Iterator: 抽象迭代器ide

namespace IteratorPattern
{
    //Iterator迭代器抽象類
    abstract class Iterator
    {
        //用於定義獲得開始對象、獲得下一個對象、
        //判斷是否到結尾、當前對象等抽象方法,統一接口
        public abstract object First();
        public abstract object Next();
        public abstract bool IsDone();
        public abstract object CurrentItem();
    }
}

ConcreteIterator: 具體迭代器工具

using System;

namespace IteratorPattern
{
    //ConcreteIterator具體迭代器類,繼承Iterator
    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 (current < aggregate.Count)
            {
                ret = aggregate[current];
            }
            return ret;
        }
        public override bool IsDone()
        {
            return current >= aggregate.Count ? true : false;
        }
        public override object CurrentItem()
        {
            return aggregate[current];//返回當前的彙集對象
        }
    }
}

Aggregate: 抽象聚合類oop

namespace IteratorPattern
{
    //Aggregate彙集抽象類
    abstract class Aggregate
    {
        //建立迭代器
        public abstract Iterator CreateIterator();
    }
}

ConcreteAggregate: 具體聚合類this

using System;
using System.Collections.Generic;

namespace IteratorPattern
{
    //ConcreteAggregate具體彙集類 繼承Aggregate
    class ConcreteAggregate : Aggregate
    {
        //聲明一個IList泛型變量,用於存放聚合對象,用ArrayList一樣能夠實現
        private IList<object> items = new List<Object>();
        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); }
        }
    }
}

Client:客戶類

using System;

namespace IteratorPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            ConcreteAggregate a = new ConcreteAggregate();
            a[0] = "張三";
            a[1] = "李四";
            a[2] = "王五";

            Iterator i = new ConcreteIterator(a);
            object item = i.First();
            while (!i.IsDone())
            {
                Console.WriteLine("{0} 請買車票!", i.CurrentItem());
                i.Next();//下一乘客
            }
            Console.Read();
        }
    }
}

模式優缺點
迭代器模式的優勢
 它支持以不一樣的方式遍歷一個聚合對象。
 迭代器簡化了聚合類。
 在同一個聚合上能夠有多個遍歷。
 在迭代器模式中,增長新的聚合類和迭代器類都很方便,無須修改原有代碼,知足「開閉原則」的要求。
迭代器模式的缺點
 因爲迭代器模式將存儲數據和遍歷數據的職責分離,增長新的聚合類須要對應增長新的迭代器類,類的個數成對增長,這在必定程度上增長了系統的複雜性。

模式適用環境
在如下狀況下可使用迭代器模式:
 訪問一個聚合對象的內容而無須暴露它的內部表示。
 須要爲聚合對象提供多種遍歷方式。
 爲遍歷不一樣的聚合結構提供一個統一的接口。

【聲明與感謝】
本文,站在許多巨人的肩膀上,借鑑和引用了許多他人擁有版權的做品或著述,在此,對前人們的貢獻致謝。並同時公佈引用的內容、原做者或來源(一些來源於互聯網的內容本人沒法追述本源,深表遺憾)。

【參考文獻】 《設計模式—可複用面向對象軟件的基礎》做者: [美] Erich Gamma / Richard Helm / Ralph Johnson / John Vlissides 譯者: 李英軍 / 馬曉星 / 蔡敏 / 劉建中 等 機械工業出版社 《重構—改善既有代碼的設計》做者: Martin Fowler譯者:候捷 中國電力出版社 《敏捷軟件開發—原則、模式與實踐》做者: Robert C. Martin 清華大學出版社 《程序員修煉之道—從小工到專家》做者: Andrew Hunt / David Thomas 電子工業出版社 《Head First 設計模式》做者: 弗里曼 譯者: O'Reilly Taiwan公司 中國電力出版社 《設計模式之禪》 做者: 秦小波 機械工業出版社 MSDN WebCast 《C#面向對象設計模式縱橫談》 講師:李建忠 劉偉. 設計模式. 北京:清華大學出版社, 2011. 劉偉. 設計模式實訓教程. 北京:清華大學出版社, 2012. 《大話設計模式》 做者: 程傑 清華大學出版社 《C#圖解教程》做者: 索利斯 譯者: 蘇林 / 朱曄 人民郵電出版社 《你必須知道的.NET》做者: 王濤 《項目中的.NET》做者: 李天平 電子工業出版社 《Microsoft .NET企業級應用架構設計》做者: (美)埃斯波西託等編著 譯者: 陳黎夫 http://www.dofactory.com/Patterns/Patterns.aspx .NET Design Patterns http://www.cnblogs.com/zhenyulu 博客做者:呂震宇 http://www.cnblogs.com/terrylee 博客做者:李會軍 http://www.cnblogs.com/anlyren/ 博客做者:anlyren http://www.cnblogs.com/idior 博客做者:idior http://www.cnblogs.com/allenlooplee 博客做者:Allen lee http://blog.csdn.net/ai92 博客做者:ai92 http://www.cnblogs.com/umlonline/ 博客做者:張傳波 http://www.cnblogs.com/lovecherry/ 博客做者:LoveCherry

相關文章
相關標籤/搜索