疊代子模式又叫遊标(Cursor)模式,是對象的行為模式。疊代子模式可以順序地通路一個聚集中的元素而不必暴露聚集的内部表象(internal representation)。
1)聚合是一個管理群組織資料對象的資料結構。
2)聚合對象主要擁有兩個職責:一是存儲内部資料;二是周遊内部資料。
3)存儲資料是聚合對象最基本的職責。
4)将周遊聚合對象中資料的行為提取出來,封裝到一個疊代器中,通過專門的疊代器來周遊聚合對象的内部資料,這就是疊代器模式的本質。疊代器模式是“單一職責原則”的完美展現。
疊代模式有兩種實作方式,分别是白箱聚集與外禀疊代子和黑箱聚集于内禀疊代子。
如果一個聚集的接口提供了可以用來修改聚集元素的方法,這個接口就是所謂的寬接口。
如果聚集對象為所有對象提供同一個接口,也就是寬接口的話,當然會滿足疊代子模式對疊代子對象的要求。但是,這樣會破壞對聚集對象的封裝。這種提供寬接口的聚集叫做白箱聚集。聚集對象向外界提供同樣的寬接口,如下圖所示:
由于聚集自己實作疊代邏輯,并向外部提供适當的接口,使得疊代子可以從外部控制聚集元素的疊代過程。這樣一來疊代子所控制的僅僅是一個遊标而已,這種疊代子叫做遊标疊代子(Cursor Iterator)。由于疊代子是在聚集結構之外的,是以這樣的疊代子又叫做外禀疊代子(Extrinsic Iterator)。
現在看一看白箱聚集與外禀疊代子的實作。一個白箱聚集向外界提供通路自己内部元素的接口(稱作周遊方法或者Traversing Method),進而使外禀疊代子可以通過聚集的周遊方法實作疊代功能。
因為疊代的邏輯是由聚集對象本身提供的,是以這樣的外禀疊代子角色往往僅僅保持疊代的遊标位置。
一個典型的由白箱聚集與外禀疊代子組成的系統如下圖所示,在這個實作中具體疊代子角色是一個外部類,而具體聚集角色向外界提供周遊聚集元素的接口。
疊代子模式涉及到以下幾個角色:
● 抽象疊代子(Iterator)角色:此抽象角色定義出周遊元素所需的接口。
● 具體疊代子(ConcreteIterator)角色:此角色實作了Iterator接口,并保持疊代過程中的遊标位置。
● 聚集(Aggregate)角色:此抽象角色給出建立疊代子(Iterator)對象的接口。
● 具體聚集(ConcreteAggregate)角色:實作了建立疊代子(Iterator)對象的接口,傳回一個合适的具體疊代子執行個體。
● 用戶端(Client)角色:持有對聚集及其疊代子對象的引用,調用疊代子對象的疊代接口,也有可能通過疊代子操作聚集元素的增加和删除。
一個常常會問的問題是:既然白箱聚集已經向外界提供了周遊方法,用戶端已經可以自行進行疊代了,為什麼還要應用疊代子模式,并建立一個疊代子對象進行疊代呢?
用戶端當然可以自行進行疊代,不一定非得需要一個疊代子對象。但是,疊代子對象和疊代模式會将疊代過程抽象化,将作為疊代消費者的用戶端與疊代負責人的疊代子責任分隔開,使得兩者可以獨立的演化。在聚集對象的種類發生變化,或者疊代的方法發生改變時,疊代子作為一個中介層可以吸收變化的因素,而避免修改用戶端或者聚集本身。
此外,如果系統需要同時針對幾個不同的聚集對象進行疊代,而這些聚集對象所提供的周遊方法有所不同時,使用疊代子模式和一個外界的疊代子對象是有意義的。具有同一疊代接口的不同疊代子對象處理具有不同周遊接口的聚集對象,使得系統可以使用一個統一的疊代接口進行所有的疊代
如果一個聚集的接口沒有提供修改聚集元素的方法,這樣的接口就是所謂的窄接口。
聚集對象為疊代子對象提供一個寬接口,而為其他對象提供一個窄接口。換言之,聚集對象的内部結構應當對疊代子對象适當公開,以便疊代子對象能夠對聚集對象有足夠的了解,進而可以進行疊代操作。但是,聚集對象應當避免向其他的對象提供這些方法,因為其他對象應當經過疊代子對象進行這些工作,而不是直接操控聚集對象。
在JAVA語言中,實作雙重接口的辦法就是将疊代子類設計成聚集類的内部成員類。這樣疊代子對象将可以像聚集對象的内部成員一樣通路聚集對象的内部結構。這種同時保證聚集對象的封裝和疊代子功能的實作的方案叫做黑箱實作方案。
由于疊代子是聚集的内部類,疊代子可以自由通路聚集的元素,是以疊代子可以自行實作疊代功能并控制對聚集元素的疊代邏輯。由于疊代子是在聚集的結構之内定義的,是以這樣的疊代子又叫做内禀疊代子(Intrinsic Iterator)。
為了說明黑箱方案的細節,這裡給出一個示意性的黑箱實作。在這個實作裡,聚集類ConcreteAggregate含有一個内部成員類ConcreteIterator,也就是實作了抽象疊代子接口的具體疊代子類,同時聚集并不向外界提供通路自己内部元素的方法。
Fail Fast
如果一個算法開始之後,它的運算環境發生變化,使得算法無法進行必需的調整時,這個算法就應當立即發出故障信号。這就是Fail Fast的含義。
如果聚集對象的元素在一個動态疊代子的疊代過程中發生變化時,疊代過程會受到影響而變得不能自恰。這時候,疊代子就應當立即抛出一個異常。這種疊代子就是實作了Fail Fast功能的疊代子。
疊代器模式的優點:
1 ) 它支援以不同的方式周遊一個聚合對象 : 複雜的聚合可用多種方式進行周遊。疊代器模式使得改變周遊算法變得很容易 : 僅需用一個不同的疊代器的執行個體代替原先的執行個體即可。你也可以自己定義疊代器的子類以支援新的周遊。
2) 疊代器簡化了聚合的接口 有了疊代器的周遊接口,聚合本身就不再需要類似的周遊接口了。這樣就簡化了聚合的接口。
3) 在同一個聚合上可以有多個周遊 每個疊代器保持它自己的周遊狀态。是以你可以同時進行多個周遊。
4)在疊代器模式中,增加新的聚合類和疊代器類都很友善,無須修改原有代碼,滿足“開閉原則”的要求。
疊代器模式的缺點
由于疊代器模式将存儲資料和周遊資料的職責分離,增加新的聚合類需要對應增加新的疊代器類,類的個數成對增加,這在一定程度上增加了系統的複雜性。
Composite :疊代器常被應用到象複合這樣的遞歸結構上。
Factory Method:多态疊代器靠Factory Method來例化适當的疊代器子類。
Memento:常與疊代器模式一起使用。疊代器可使用一個 Memento來捕獲一個疊代的狀态。疊代器在其内部存儲Memento。