Skip to content
June 9, 2013 / windperson

迭代器模式(Iterator Pattern)

迭代器模式是一個現在幾乎大家都在使用,但卻不太會發現原來這也是個軟體設計模式的設設計模式,GoF的Design Pattern這本書之中對迭代模式的定義如下:

“Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation”

迭代器模式提供一種通用的方式來依序存取聚合物件之中的各個成員元素,UML類別圖如下:
Iterator Pattern

  • Aggregate:一個聚合物件類別的抽象介面,其中的CreateIterator()方法宣告,就是用來規範說,繼承該介面的類別需提供一個產生該類別專屬迭代器物件的方法。
  • ConcreteAggregate:實作Aggregate介面的聚合物件類別,實際實作了公開的CreateIterator()方法來讓client端使用此方法產生對應的專屬迭代器
  • Iterator:迭代器物件的抽象方法介面,定義了幾個存取聚合物件內成員元素的方法,First()以取得該聚合物件的第一個元素,依序呼叫Next()就可以一一依序得到聚合物件內的所有元素,利用呼叫IsDone()來確認是否還能再繼續呼叫Next()來取得下一個元素,CurrentItem()來取得現在Iterator迭代器內部存取成員元素機制目前所指向的元素。
  • ConcreateIterator:對應某一特定的ConcreateAggregate物件,會有至少一個特定的專屬迭代器,也就是ConcreateIterator類別的物件,是利用ConcreateAggregate所實作的CreatIterator()方法來產生。

在此架構上,聚合物件類別(也就是實作Aggregate的類別)的物件,負責對於實際上該類別內包含的成員元素之新增刪除,而迭代器(也就是實作Iterator的類別)負責讀取和遍歷所有的成員元素,也是一種SoC(Separation of Concern)概念的設計。

由於迭代器模式使用非常廣泛和頻繁,現今的大多數物件導向程式設計語言的函式庫都有提供現成的Aggregate和Iterator介面,再加上程式語言語法上對於迭代器模式的支持,例如C#和Java的foreach語法,使得這個迭代器模式雖然寫程式時都會使用到,但已經被程式語言的語法包裝內化到我們沒發現到原來這內部機制也是一種設計模式。

因此,現在幾乎很少會有需要自己特別來定義新物件類別實作迭代器模式,通常是使用該語言就有提供的原生Iterator介面(例如在C#裡面的IEnumerableIEnumerator介面,Java的IterableIterator介面),並實作其介面上的方法,就可以支援該程式語言所提供的簡便語法了,甚至如果是使用函式庫內建的聚合類別(如List, Dictionary, Queue, HashMap等等)的話,函式庫連迭代器都已經準備好可以直接使用。

會用到迭代器模式的情況有:

  • 聚合物件內部結構複雜,而希望簡化client端存取的程式碼。
  • 提拱按照某一種以上的既定方式來輸出或處理聚合物件內部所有的成員元素。
  • 提供聚合物件只選取部分成員元素給客戶端程式的功能。
  • 實務上須處理的聚合物件有一種以上的複數個聚合物件,又希望能提供給客戶端程式對那些聚合物件中的成員元素提供一致性的存取方法時。
  • 聚合物件本身或其實作在未來有可能被置換掉,但又不希望得修改寫客戶端程式。
  • 聚合物件實際上根本或是因某些因素而沒有儲存成員元素的實體物件,而又希望能讓客戶端程式碼能像普通聚合物件般存取其內容時。
Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: