一、什麼是迭代器模式
迭代器這個詞在Java中出現過,即Java中使用Iterator迭代器對集合進行遍歷,但迭代器模式算是一個沒落的模式,基本上沒人會單獨寫一個迭代器,除非是產品性質的開發。
迭代器模式(Iterator),提供一種方法順序訪問一個聚合物件中各個元素,而又不暴露該物件的內部表示。UML結構圖如下:
其中,Aggregate是聚集抽象類,負責提供建立具體迭代器角色的介面;Iterator是迭代抽象類,用於定義得到開始物件、得到下一個物件、判斷是否到結尾、當前物件等抽象方法,統一介面;ConcreteAggregate是具體聚集類,繼承Aggregate;ConcreteIterator是具體迭代器類,繼承Iterator,實現開始、下一個、是否結尾、當前物件等方法。
1. 抽象容器
負責提供介面,比如存在一個類似createIterator()這樣的方法,在Java中一般是iterator()方法。
1 public interface Aggregate { 2 3 public void add(Object object); 4 5 public void remove(Object object); 6 7 public Iterator iterator(); 8 9 }
2. 抽象迭代器
負責定義訪問和遍歷元素的介面,基本上有固定的三個方法,即first()獲取第一個元素、next()訪問下一個元素、hasNext()是否已經遍歷到底部。
1 public interface Iterator { 2 3 public Object next(); //遍歷到下一個元素 4 5 public boolean hasNext(); //是否已經遍歷到尾部 6 7 public boolean remove(); //刪除當前指向的元素 8 9 }
3. 具體容器
1 public class ConcreteAggregate implements Aggregate { 2 3 private Vector vector = new Vector(); 4 5 @Override 6 public void add(Object object) { 7 this.vector.add(object); 8 } 9 10 public void remove(Object object) { 11 this.remove(object); 12 } 13 14 @Override 15 public Iterator iterator() { 16 return new ConcreteIterator(this.vector); 17 } 18 19 }
4. 具體迭代器
簡單的實現就是通過一個遊標,在一個容器中上下翻滾,遍歷所有它需要檢視的元素。
1 public class ConcreteIterator implements Iterator { 2 3 private Vector vector = new Vector(); 4 public int cursor = 0; //定義當前遊標 5 6 public ConcreteIterator(Vector vector) { 7 this.vector = vector; 8 } 9 10 @Override 11 public Object next() { 12 Object result = null; 13 14 if (this.hasNext()) { 15 result = this.vector.get(this.cursor ++); 16 } else { 17 result = null; 18 } 19 20 return result; 21 } 22 23 @Override 24 public boolean hasNext() { 25 if (this.cursor == this.vector.size()) { 26 return false; 27 } 28 29 return true; 30 } 31 32 @Override 33 public boolean remove() { 34 this.vector.remove(this.cursor); 35 36 return true; 37 } 38 39 }
5. Client客戶端
下面測試一下,注意引入自定義的Iterator類,而不是Java封裝好的Iterator類。
1 public class Client { 2 3 public static void main(String[] args) { 4 Aggregate aggregate = new ConcreteAggregate(); 5 aggregate.add("abc"); 6 aggregate.add("aaa"); 7 aggregate.add("1234"); 8 9 //遍歷 10 Iterator iterator = aggregate.iterator(); 11 while (iterator.hasNext()) { 12 System.out.println(iterator.next()); 13 } 14 } 15 16 }
執行結果如下:
二、迭代器模式的應用
1. 何時使用
- 遍歷一個聚合物件時
2. 方法
- 把在元素間遊走的責任交給迭代器,而不是聚合物件
3. 優點
- 支援以不同的方式遍歷一個聚合物件
- 迭代器簡化了聚合類
- 在同一個聚合上可以有多個遍歷
- 增加新的聚合類和迭代器類都很方便,無需修改原有程式碼
4. 缺點
- 增加了系統的複雜性。因為迭代器模式將儲存資料和遍歷資料的職責分離,增加了新的聚合類需要對應增加新的迭代器類,增加了系統的複雜性。
5. 使用場景
- 訪問一個聚合物件的內容無需暴露它的內部表示時
- 需要為聚合物件提供多種便利方式時
- 為遍歷不同的聚合結構提供一個統一的介面
6. 應用例項
- Java中的Iterator迭代器
- foreach遍歷
三、迭代器模式的實現
這部分內容就不再贅述了,具體實現與上方程式碼沒有太大區別,根據具體應用場景加以改變即可,當然也可以參考java.util.Iterator的原始碼。
到此,常見的23種設計模式就介紹完了,所有原始碼皆已上傳至碼雲,至於擴充套件的新模式(常用23個設計模式之外的設計模式),後續有機會會繼續更新,短時間內不再編寫有關設計模式的內容。