提供一種方法順序訪問一個聚合對象中各個元素, 而又無須暴露該對象的內部表示。java
迭代器模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既能夠作到不暴露集合的內部結構,又可以讓外部代碼透明地訪問集合內部的數據。apache
迭代模式使用比較少,JDK集合也提供了Iterator的具體實現,能夠直接拿來用,沒必要本身實現編程
一、訪問一個聚合對象的內容而無須暴露它的內部表示。設計模式
二、須要爲聚合對象提供多種遍歷方式。數組
三、爲遍歷不一樣的聚合結構提供一個統一的接口。mybatis
優勢: 一、它支持以不一樣的方式遍歷一個聚合對象。 二、迭代器簡化了聚合類。 三、在同一個聚合上能夠有多個遍歷。 四、在迭代器模式中,增長新的聚合類和迭代器類都很方便,無須修改原有代碼。ide
缺點:因爲迭代器模式將存儲數據和遍歷數據的職責分離,增長新的聚合類須要對應增長新的迭代器類,類的個數成對增長,這在必定程度上增長了系統的複雜性。測試
1.三、類圖角色及其職責this
一、Iterator(迭代器接口):spa
該接口必須定義實現迭代功能的最小定義方法集
好比提供hasNext()和next()方法。
二、ConcreteIterator(迭代器實現類):
迭代器接口Iterator的實現類。能夠根據具體狀況加以實現。
三、Aggregate(容器接口):
定義基本功能以及提供相似Iterator iterator()的方法。
四、concreteAggregate(容器實現類):
容器接口的實現類。必須實現Iterator iterator()方法。
建立一個容器中要存儲的內容Book
public class Book { private String id; private String name; private double price; public Book(String id, String name, double price) { this.id = id; this.name = name; this.price = price; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public void display() { System.out.println("ID=" + id + ",\tname=" + name + ",\tprice" + price); } }
建立一個容器BookList
public class BookList { //容器內部仍是一個List,也能夠用數組 private List<Book> bookList = new ArrayList<Book>(); private int index; //添加書籍 public void addBook(Book book){ bookList.add(book); } //刪除書籍 public void removeBook(Book book){ int bookIndex = bookList.indexOf(book); bookList.remove(bookIndex); } //判斷是否有下一本書 public boolean hasNext(){ if(index >= bookList.size()){ return false; } return true; } //得到下一本書 public Book getNext(){ return bookList.get(index++); } //獲取集合長度 public int getSize(){ return bookList.size(); } //根據index獲取Book public Book getByIndex(int index){ return bookList.get(index); } }
接下來,就是迭代容器了
方式1、(由容器本身實現順序遍歷。直接在容器類裏直接添加順序遍歷方法)
@Test public void test1() { BookList bookList = new BookList(); Book book1 = new Book("001","設計模式",200); Book book2 = new Book("002","Java核心編程",200); Book book3 = new Book("003","計算機組成原理",200); bookList.addBook(book1); bookList.addBook(book2); bookList.addBook(book3); while(bookList.hasNext()){ Book book = bookList.getNext(); book.display(); } }
輸出
ID=001, name=設計模式, price200.0 ID=002, name=Java核心編程, price200.0 ID=003, name=計算機組成原理, price200.0
方式2、讓調用者本身實現遍歷。直接暴露數據細節給外部)
@Test public void test2() { BookList bookList = new BookList(); Book book1 = new Book("001", "設計模式", 200); Book book2 = new Book("002", "Java核心編程", 200); Book book3 = new Book("003", "計算機組成原理", 200); bookList.addBook(book1); bookList.addBook(book2); bookList.addBook(book3); for (int i = 0; i < bookList.getSize(); i++) { Book book = bookList.getByIndex(i); book.display(); } }
結果同上
以上方法1與方法2均可以實現對遍歷,但有這些問題
1,容器類承擔了太多功能:一方面須要提供添加刪除等自己應有的功能;一方面還須要提供遍歷訪問功能。
2,每每容器在實現遍歷的過程當中,須要保存遍歷狀態,當跟元素的添加刪除等功能夾雜在一塊兒,很容易引發混亂和程序運行錯誤等。
Iterator模式就是爲了有效地處理按順序進行遍歷訪問的一種設計模式,簡單地說,Iterator模式提供一種有效的方法,能夠屏蔽彙集對象集合的容器類的實現細節,而能對容器內包含的對象元素按順序進行有效的遍歷訪問。
因此,Iterator模式的應用場景能夠概括爲知足如下幾個條件:
一、訪問容器中包含的內部對象
二、按順序訪問
用代碼實現一下迭代模式,只需修改BookList便可,BookListIterator
public class BookListIterator { //容器內部仍是一個List,也能夠用數組 private List<Book> bookList = new ArrayList<Book>(); private int index; //添加書籍 public void addBook(Book book){ bookList.add(book); } //刪除書籍 public void removeBook(Book book){ int bookIndex = bookList.indexOf(book); bookList.remove(bookIndex); } //獲取集合長度 public int getSize(){ return bookList.size(); } //根據index獲取Book public Book getByIndex(int index){ return bookList.get(index); } //獲得Iterator實例 public Iterator Iterator() { return new Itr(); } //內部類,Iterator實例(由於要使用容器的內部信息,因此要寫成內部類) private class Itr implements Iterator{ //判斷是否有下一本書,將剛纔hasNext()中內容複製過來便可 public boolean hasNext() { if(index >= bookList.size()){ return false; } return true; } //得到下一本書,將剛纔getNext()中內容複製過來便可 public Object next() { return bookList.get(index++); } public void remove() { } } }
測試
@Test public void test3() { BookListIterator bookList = new BookListIterator(); Book book1 = new Book("001","設計模式",200); Book book2 = new Book("002","Java核心編程",200); Book book3 = new Book("003","計算機組成原理",200); bookList.addBook(book1); bookList.addBook(book2); bookList.addBook(book3); Iterator iterator = bookList.Iterator(); while(iterator.hasNext()){ Book book = (Book) iterator.next(); book.display(); } }
輸出同上
能夠看到,這和使用JDK提供集合的Iterator方法就如出一轍了。
java.util.Iterator
java.util.ArrayList中的Itr
org.apache.ibatis.cursor.defaults.DefaultCursor的cursorIterator
c