1. 程式人生 > >設計模式(十九)—迭代器模式(行為型)

設計模式(十九)—迭代器模式(行為型)

一、簡介(Brief Introduction)

       提供一種方法順序訪問一個聚合物件中各個元素,而又不需暴露該物件的內部表示

例子1:電視遙控器的頻道遍歷

 

二、模式分析(Analysis)


Iterator(迭代器):迭代器定義訪問和遍歷元素的介面

ConcreteIterator(具體迭代器):具體迭代器實現迭代器介面,對該聚合遍歷時跟蹤當前位置,跟蹤聚合中的當前物件,並能夠計算出待遍歷的後繼物件

Aggregate(聚合):聚合定義建立相應迭代器物件的介面

ConcreteAggregate(具體聚合):具體聚合實現建立相應迭代器的介面,該操作返回ConcreteIterator的一個適當的例項

三、案例分析(Example)

namespace 迭代器
{

1、客戶端

   class Program
    {
        static void Main(string[] args)
        {
            ConcrteAggregate a = new ConcrteAggregate();
            a[0] = "大鳥";
            a[1] = "小菜";
            a[2] = "行李";
            a[3] = "老外";
            a[4] = "公交內部員工";
            a[5] = "小偷";

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

        }
    }
 2、Itrator迭代器抽象類
    abstract class Iterator
    {
        public abstract object First();
        public abstract object Next();
        public abstract bool IsDone();
        public abstract object CurrentItem();
    }
 3、Aggregate聚集抽象類
    abstract class Aggregate
    {
        public abstract Iterator CreateIterator();
    }

    //concreteIterator具體迭代器,繼承Iterator
    class ConcreteIterator : Iterator
    {
        private ConcrteAggregate aggregate;   
        private int current = 0;

        public ConcreteIterator(ConcrteAggregate  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];
        }
    }
 4、ConcreteAggregate具體聚集類,
  class ConcrteAggregate : Aggregate
    {
        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 );}
        }
      
    }
   
}

四、解決的問題(What To Solve)

迭代器模式可用來:

• 訪問一個聚合物件的內容而無需暴露它的內部表示。

• 需要為聚合物件提供多種遍歷方式。

• 為遍歷不同的聚合結構提供一個統一的介面 (即, 支援多型迭代)

      迭代器模式是與集合共生共死的,一般來說,我們只要實現一個集合,就需要同時提供這個集合的迭代器。假如我們要實現一個這樣的新的容器,當然也需要引入迭代器模式,給我們的容器實現一個迭代器。

      但是,由於容器與迭代器的關係太密切了,所以大多數語言在實現容器的時候都給提供了迭代器,並且這些語言提供的容器和迭代器在絕大多數情況下就可以滿足我 們的需要,所以現在需要我們自己去實踐迭代器模式的場景還是比較少見的,我們只需要使用語言中已有的容器和迭代器就可以了。

五、優缺點(Advantage and Disadvantage)

優點:

1 )它支援以不同的方式遍歷一個聚合物件 : 複雜的聚合可用多種方式進行遍歷。迭代器模式使得改變遍歷演算法變得很容易 : 僅需用一個不同的迭代器的例項代替原先的例項即可。你也可以自己定義迭代器的子類以支援新的遍歷。

2) 迭代器簡化了聚合的介面有了迭代器的遍歷介面,聚合本身就不再需要類似的遍歷介面了。這樣就簡化了聚合的介面。

3) 在同一個聚合上可以有多個遍歷每個迭代器保持它自己的遍歷狀態。因此你可以同時進行多個遍歷。

4)在迭代器模式中,增加新的聚合類和迭代器類都很方便,無須修改原有程式碼,滿足“開閉原則”的要求。

5)封裝性良好,使用者只需要得到迭代器就可以遍歷,而對於遍歷演算法則不用去關心。

缺點

         由於迭代器模式將儲存資料和遍歷資料的職責分離,增加新的聚合類需要對應增加新的迭代器類,類的個數成對增加,這在一定程度上增加了系統的複雜性。對於比較簡單的遍歷(像陣列或者有序列表),使用迭代器方式遍歷較為繁瑣,大家可能都有感覺,像ArrayList,我們寧可願意使用for迴圈和get方法來遍歷集合。

六、擴充套件(Extend)

1)聚合是一個管理和組織資料物件的資料結構。

2)聚合物件主要擁有兩個職責:一是儲存內部資料;二是遍歷內部資料。

3)儲存資料是聚合物件最基本的職責。

4)將遍歷聚合物件中資料的行為提取出來,封裝到一個迭代器中,通過專門的迭代器來遍歷聚合物件的內部資料,這就是迭代器模式的本質。迭代器模式是“單一職責原則”的完美體現。

七、聯絡(Link)

Composite :迭代器常被應用到象複合這樣的遞迴結構上。

FactoryMethod:多型迭代器靠Factory Method來例化適當的迭代器子類。

Memento:常與迭代器模式一起使用。迭代器可使用一個 Memento來捕獲一個迭代的狀態。迭代器在其內部儲存Memento。

八、總結(Summary)

         迭代器結合了封裝和多型的面向物件程式設計原理。使用迭代器,你可以對集合中的物件進行操作,而無需專門瞭解集合如何顯現或者集合包含什麼(物件的種 類)。迭代器提供了不同固定迭代實現的統一介面,它完全包含了如何操縱特定集合的詳細資訊,包括顯示哪些項(過濾)及其顯示順序(排序)。