# 遍歷聚合對象中的元素——迭代器模式(二)
2 迭代器模式概述
在軟件開發中,我們經常需要使用聚合對象來存儲一系列數據。聚合對象擁有兩個職責:一是存儲數據;二是遍歷數據。從依賴性來看,前者是聚合對象的基本職責;而后者既是可變化的,又是可分離的。因此,可以將遍歷數據的行為從聚合對象中分離出來,封裝在一個被稱之為“迭代器”的對象中,由迭代器來提供遍歷聚合對象內部數據的行為,這將簡化聚合對象的設計,更符合“單一職責原則”的要求。
迭代器模式定義如下:
迭代器模式(Iterator Pattern):提供一種方法來訪問聚合對象,而不用暴露這個對象的內部表示,其別名為游標(Cursor)。迭代器模式是一種對象行為型模式。
在迭代器模式結構中包含聚合和迭代器兩個層次結構,考慮到系統的靈活性和可擴展性,在迭代器模式中應用了工廠方法模式,其模式結構如圖3所示:

圖3 迭代器模式結構圖
在迭代器模式結構圖中包含如下幾個角色:
● Iterator(抽象迭代器):它定義了訪問和遍歷元素的接口,聲明了用于遍歷數據元素的方法,例如:用于獲取第一個元素的first()方法,用于訪問下一個元素的next()方法,用于判斷是否還有下一個元素的hasNext()方法,用于獲取當前元素的currentItem()方法等,在具體迭代器中將實現這些方法。
● ConcreteIterator(具體迭代器):它實現了抽象迭代器接口,完成對聚合對象的遍歷,同時在具體迭代器中通過游標來記錄在聚合對象中所處的當前位置,在具體實現時,游標通常是一個表示位置的非負整數。
● Aggregate(抽象聚合類):它用于存儲和管理元素對象,聲明一個createIterator()方法用于創建一個迭代器對象,充當抽象迭代器工廠角色。
● ConcreteAggregate(具體聚合類):它實現了在抽象聚合類中聲明的createIterator()方法,該方法返回一個與該具體聚合類對應的具體迭代器ConcreteIterator實例。
在迭代器模式中,提供了一個外部的迭代器來對聚合對象進行訪問和遍歷,迭代器定義了一個訪問該聚合元素的接口,并且可以跟蹤當前遍歷的元素,了解哪些元素已經遍歷過而哪些沒有。迭代器的引入,將使得對一個復雜聚合對象的操作變得簡單。
下面我們結合代碼來對迭代器模式的結構進行進一步分析。在迭代器模式中應用了工廠方法模式,抽象迭代器對應于抽象產品角色,具體迭代器對應于具體產品角色,抽象聚合類對應于抽象工廠角色,具體聚合類對應于具體工廠角色。
在抽象迭代器中聲明了用于遍歷聚合對象中所存儲元素的方法,典型代碼如下所示:
```
interface Iterator {
public void first(); //將游標指向第一個元素
public void next(); //將游標指向下一個元素
public boolean hasNext(); //判斷是否存在下一個元素
public Object currentItem(); //獲取游標指向的當前元素
}
```
在具體迭代器中將實現抽象迭代器聲明的遍歷數據的方法,如下代碼所示:
```
class ConcreteIterator implements Iterator {
private ConcreteAggregate objects; //維持一個對具體聚合對象的引用,以便于訪問存儲在聚合對象中的數據
private int cursor; //定義一個游標,用于記錄當前訪問位置
public ConcreteIterator(ConcreteAggregate objects) {
this.objects=objects;
}
public void first() { ...... }
public void next() { ...... }
public boolean hasNext() { ...... }
public Object currentItem() { ...... }
}
```
需要注意的是抽象迭代器接口的設計非常重要,一方面需要充分滿足各種遍歷操作的要求,盡量為各種遍歷方法都提供聲明,另一方面又不能包含太多方法,接口中方法太多將給子類的實現帶來麻煩。因此,可以考慮使用抽象類來設計抽象迭代器,在抽象類中為每一個方法提供一個空的默認實現。如果需要在具體迭代器中為聚合對象增加全新的遍歷操作,則必須修改抽象迭代器和具體迭代器的源代碼,這將違反“開閉原則”,因此在設計時要考慮全面,避免之后修改接口。
聚合類用于存儲數據并負責創建迭代器對象,最簡單的抽象聚合類代碼如下所示:
```
interface Aggregate {
Iterator createIterator();
}
```
具體聚合類作為抽象聚合類的子類,一方面負責存儲數據,另一方面實現了在抽象聚合類中聲明的工廠方法createIterator(),用于返回一個與該具體聚合類對應的具體迭代器對象,代碼如下所示:
```
class ConcreteAggregate implements Aggregate {
......
public Iterator createIterator() {
return new ConcreteIterator(this);
}
......
}
```
思考
> 理解迭代器模式中具體聚合類與具體迭代器類之間存在的依賴關系和關聯關系。
- Introduction
- 基礎知識
- 設計模式概述
- 從招式與內功談起——設計模式概述(一)
- 從招式與內功談起——設計模式概述(二)
- 從招式與內功談起——設計模式概述(三)
- 面向對象設計原則
- 面向對象設計原則之單一職責原則
- 面向對象設計原則之開閉原則
- 面向對象設計原則之里氏代換原則
- 面向對象設計原則之依賴倒轉原則
- 面向對象設計原則之接口隔離原則
- 面向對象設計原則之合成復用原則
- 面向對象設計原則之迪米特法則
- 六個創建型模式
- 簡單工廠模式-Simple Factory Pattern
- 工廠三兄弟之簡單工廠模式(一)
- 工廠三兄弟之簡單工廠模式(二)
- 工廠三兄弟之簡單工廠模式(三)
- 工廠三兄弟之簡單工廠模式(四)
- 工廠方法模式-Factory Method Pattern
- 工廠三兄弟之工廠方法模式(一)
- 工廠三兄弟之工廠方法模式(二)
- 工廠三兄弟之工廠方法模式(三)
- 工廠三兄弟之工廠方法模式(四)
- 抽象工廠模式-Abstract Factory Pattern
- 工廠三兄弟之抽象工廠模式(一)
- 工廠三兄弟之抽象工廠模式(二)
- 工廠三兄弟之抽象工廠模式(三)
- 工廠三兄弟之抽象工廠模式(四)
- 工廠三兄弟之抽象工廠模式(五)
- 單例模式-Singleton Pattern
- 確保對象的唯一性——單例模式 (一)
- 確保對象的唯一性——單例模式 (二)
- 確保對象的唯一性——單例模式 (三)
- 確保對象的唯一性——單例模式 (四)
- 確保對象的唯一性——單例模式 (五)
- 原型模式-Prototype Pattern
- 對象的克隆——原型模式(一)
- 對象的克隆——原型模式(二)
- 對象的克隆——原型模式(三)
- 對象的克隆——原型模式(四)
- 建造者模式-Builder Pattern
- 復雜對象的組裝與創建——建造者模式(一)
- 復雜對象的組裝與創建——建造者模式(二)
- 復雜對象的組裝與創建——建造者模式(三)
- 七個結構型模式
- 適配器模式-Adapter Pattern
- 不兼容結構的協調——適配器模式(一)
- 不兼容結構的協調——適配器模式(二)
- 不兼容結構的協調——適配器模式(三)
- 不兼容結構的協調——適配器模式(四)
- 橋接模式-Bridge Pattern
- 處理多維度變化——橋接模式(一)
- 處理多維度變化——橋接模式(二)
- 處理多維度變化——橋接模式(三)
- 處理多維度變化——橋接模式(四)
- 組合模式-Composite Pattern
- 樹形結構的處理——組合模式(一)
- 樹形結構的處理——組合模式(二)
- 樹形結構的處理——組合模式(三)
- 樹形結構的處理——組合模式(四)
- 樹形結構的處理——組合模式(五)
- 裝飾模式-Decorator Pattern
- 擴展系統功能——裝飾模式(一)
- 擴展系統功能——裝飾模式(二)
- 擴展系統功能——裝飾模式(三)
- 擴展系統功能——裝飾模式(四)
- 外觀模式-Facade Pattern
- 深入淺出外觀模式(一)
- 深入淺出外觀模式(二)
- 深入淺出外觀模式(三)
- 享元模式-Flyweight Pattern
- 實現對象的復用——享元模式(一)
- 實現對象的復用——享元模式(二)
- 實現對象的復用——享元模式(三)
- 實現對象的復用——享元模式(四)
- 實現對象的復用——享元模式(五)
- 代理模式-Proxy Pattern
- 設計模式之代理模式(一)
- 設計模式之代理模式(二)
- 設計模式之代理模式(三)
- 設計模式之代理模式(四)
- 十一個行為型模式
- 職責鏈模式-Chain of Responsibility Pattern
- 請求的鏈式處理——職責鏈模式(一)
- 請求的鏈式處理——職責鏈模式(二)
- 請求的鏈式處理——職責鏈模式(三)
- 請求的鏈式處理——職責鏈模式(四)
- 命令模式-Command Pattern
- 請求發送者與接收者解耦——命令模式(一)
- 請求發送者與接收者解耦——命令模式(二)
- 請求發送者與接收者解耦——命令模式(三)
- 請求發送者與接收者解耦——命令模式(四)
- 請求發送者與接收者解耦——命令模式(五)
- 請求發送者與接收者解耦——命令模式(六)
- 解釋器模式-Interpreter Pattern
- 自定義語言的實現——解釋器模式(一)
- 自定義語言的實現——解釋器模式(二)
- 自定義語言的實現——解釋器模式(三)
- 自定義語言的實現——解釋器模式(四)
- 自定義語言的實現——解釋器模式(五)
- 自定義語言的實現——解釋器模式(六)
- 迭代器模式-Iterator Pattern
- 遍歷聚合對象中的元素——迭代器模式(一)
- 遍歷聚合對象中的元素——迭代器模式(二)
- 遍歷聚合對象中的元素——迭代器模式(三)
- 遍歷聚合對象中的元素——迭代器模式(四)
- 遍歷聚合對象中的元素——迭代器模式(五)
- 遍歷聚合對象中的元素——迭代器模式(六)
- 中介者模式-Mediator Pattern
- 協調多個對象之間的交互——中介者模式(一)
- 協調多個對象之間的交互——中介者模式(二)
- 協調多個對象之間的交互——中介者模式(三)
- 協調多個對象之間的交互——中介者模式(四)
- 協調多個對象之間的交互——中介者模式(五)
- 備忘錄模式-Memento Pattern
- 撤銷功能的實現——備忘錄模式(一)
- 撤銷功能的實現——備忘錄模式(二)
- 撤銷功能的實現——備忘錄模式(三)
- 撤銷功能的實現——備忘錄模式(四)
- 撤銷功能的實現——備忘錄模式(五)
- 觀察者模式-Observer Pattern
- 對象間的聯動——觀察者模式(一)
- 對象間的聯動——觀察者模式(二)
- 對象間的聯動——觀察者模式(三)
- 對象間的聯動——觀察者模式(四)
- 對象間的聯動——觀察者模式(五)
- 對象間的聯動——觀察者模式(六)
- 狀態模式-State Pattern
- 處理對象的多種狀態及其相互轉換——狀態模式(一)
- 處理對象的多種狀態及其相互轉換——狀態模式(二)
- 處理對象的多種狀態及其相互轉換——狀態模式(三)
- 處理對象的多種狀態及其相互轉換——狀態模式(四)
- 處理對象的多種狀態及其相互轉換——狀態模式(五)
- 處理對象的多種狀態及其相互轉換——狀態模式(六)
- 策略模式-Strategy Pattern
- 算法的封裝與切換——策略模式(一)
- 算法的封裝與切換——策略模式(二)
- 算法的封裝與切換——策略模式(三)
- 算法的封裝與切換——策略模式(四)
- 模板方法模式-Template Method Pattern
- 模板方法模式深度解析(一)
- 模板方法模式深度解析(二)
- 模板方法模式深度解析(三)
- 訪問者模式-Visitor Pattern
- 操作復雜對象結構——訪問者模式(一)
- 操作復雜對象結構——訪問者模式(二)
- 操作復雜對象結構——訪問者模式(三)
- 操作復雜對象結構——訪問者模式(四)
- 設計模式趣味學習(復習)
- 設計模式與足球(一)
- 設計模式與足球(二)
- 設計模式與足球(三)
- 設計模式與足球(四)
- 設計模式綜合應用實例
- 多人聯機射擊游戲
- 多人聯機射擊游戲中的設計模式應用(一)
- 多人聯機射擊游戲中的設計模式應用(二)
- 數據庫同步系統
- 設計模式綜合實例分析之數據庫同步系統(一)
- 設計模式綜合實例分析之數據庫同步系統(二)
- 設計模式綜合實例分析之數據庫同步系統(三)