設計模式之Iterator-迭代器模式

Iterator模式也叫迭代模式,是由GoF提出的23種設計模式的一種。Iterator模式是行爲模式之一,它把對容器中包含的內部對象的訪問委讓給外部類,使用Iterator(遍歷)按順序進行遍歷訪問的設計模式。

本文介紹設計模式中的迭代(Iterator)模式的概念,用法,以及實際應用中怎麼樣使用迭代模式進行開發。
Iterator模式的概念

Iterator模式指對容器中包含的內部對象的訪問委讓給外部類,使用Iterator(遍歷)按順序進行遍歷訪問的設計模式。
在程序設計中,經常有這種情況,需要從大量得數據(對象)集合中一個個地取出數據加以處理。Iterator模式就是爲了有效地處理按順序進行遍歷訪問的一種設計模式,簡單地說,Iterator模式提供一種有效的方法,可以屏蔽聚集對象集合的容器類的實現細節,而能對容器內包含的對象元素按順序進行有效的遍歷訪問。
所以,Iterator模式的應用場景可以歸納爲滿足以下幾個條件:
- 訪問容器中包含的內部對象
- 按順序訪問

爲什麼需要Iterator模式
在應用Iterator模式之前,首先應該明白Iterator模式用來解決什麼問題。或者說,如果不使用Iterator模式,會存在什麼問題。
我們舉例來說明Iterator模式到底好在哪。

比如有一個Book類,一個管理Book的容器類BookList:
public class Book {
    ...
}

public class BookList {
    //保存Book對象數據
    private List bookList = new ArrayList();

    //添加Book對象至BookList容器
    public void addBook(Book book) {
        ...
    }

    //從BookList容器刪除Book對象
    public void deleteBook(Book book) {
        ...
    }

    //其他方法
    ...
}


我們需要按順序遍歷訪問BookList包含的Book對象。
怎麼實現順序遍歷方法呢?

你可能會考慮以下這些遍歷方法:
方法1,由容器自己實現順序遍歷。直接在BookList裏直接添加順序遍歷方法:
public class BookList {
    private int index;
    ...
    //得到當前Book
    public Book getCurrentBook() {
        ...
        Book book = (Book)bookList.get(index);
        ...
        return book;
    }

    //是否存在下一個Book
    public boolean hasNext() {
        ...
    }
}


使用時,可能的使用方法是:
BookList bookList = ...;
...
while (bookList.hasNext()) {
    Book book = bookList.getCurrentBook();
    //對Book加以處理(略)
    ...
}


方法2,讓調用者自己實現遍歷。直接暴露BookList數據細節給外部,比如:
public class BookList {
    ...
    public Book getBookList() {
        ...
        return bookList;
    }
}


可能的使用方法爲:
BookList bookList = ...;
List <Book>bookDataList = bookList.getBookList();
...
for (int i=0; bookDataList != null && i<bookDataList.size(); i++) {
    Book book = bookDataList.get(i);
    //對Book加以處理(略)
    ...
}


以上方法1與方法2都可以實現對BookList所包含的Book對象進行遍歷,這樣有問題呢?
確實使用上沒有任何問題。
但實現方法1中,
1,容器類BookList承擔了太多功能:一方面需要提供添加刪除等BookList本身應有的功能;一方面還需要提供遍歷訪問功能。
2,往往容器在實現遍歷的過程中,需要保存遍歷狀態,當跟元素的添加刪除等功能夾雜在一起,很容易引起混亂和程序運行錯誤等。

在實現方法2中,
容器本身未實現任何遍歷方法,把這個遍歷的任務交給了調用者,這樣一來,暴露了容器本身的實現細節,如果一旦容器內部的數據接口發生變化,比如由於某種原因,BookList的List bookList用Map bookList來實現,這樣,所有調用方的程序不得不隨着BookList的修改而修改。


Iterator模式很好地解決了以上問題。
我們先從JDK中的Collection Framework對Iterator模式的實現方法來說明Iterator模式。

Java Collections Framework - Java集合框架List,Map,Set等全面介紹之概要篇


Java Collection Framework對迭代模式的經典實現
1,迭代接口:Iterator接口,定義了遍歷接口:
public interface Iterator
{
    //判斷是否存在下一個元素
    public abstract boolean hasNext();
    //返回下一個可用的元素
    public abstract Object next();
    //移除當前元素
    public abstract void remove();
}


2,容器接口:Collection接口,定義了iterator()方法,把遍歷委讓給Iterator的實現類。
public interface Collection
    extends Iterable
{
    ...
    //取得對所有元素的遍歷。可以通過Iterator提供的方法遍歷集合的元素
    public abstract Iterator iterator();
    ...
}


3,容器接口Collection的實現類與迭代接口Iterator的實現類:
public abstract class AbstractList extends AbstractCollection implements List {
    ...
    //負責創建具體迭代器角色的工廠方法
    public Iterator iterator() {
        //把遍歷委讓給Iterator的實現類Itr。
        return new Itr();
    }

    //迭代接口Iterator的實現類
    private class Itr implements Iterator {
        ...
    }
    ...
}


public class ArrayList extends AbstractList {
    ...
}


以上說明了Java Collection Framework裏的對Iterator模式的基本實現方法。

這也是Iterator模式一種經典的實現方案。

經典的Iterator模式實現方案
下面是一種比較經典的Iterator模式實現方案,該實現方案基於接口設計原則,設計了以下幾個接口或類:
迭代器接口Iterator:該接口必須定義實現迭代功能的最小定義方法集比如提供hasNext()和next()方法。
迭代器實現類:迭代器接口Iterator的實現類。可以根據具體情況加以實現。
容器接口:定義基本功能以及提供類似Iterator iterator()的方法。
容器實現類:容器接口的實現類。必須實現Iterator iterator()方法。

Iterator模式的類圖:

[該圖出自Wikipedia]

應用我們的上面介紹的例子,我們需要定義以下幾個接口與類:
public class public interface IBookList {
    public BookListIterator iterator();
}
BookListImpl implements IBookList {
    public BookListIterator iterator() {
        return new BookListIteratorImpl(this);
    }
}
public interface BookListIterator {
    public boolean hasNext();
    public Book next();
}
public class BookListIteratorImpl implements BookListIterator {
    ...(具體實現過程略)
}


對容器的遍歷方法例:
IBookList list = ...;
BookListIterator it = list.iterator();
while(it.hasNext()){
    Book book = it.next();
    ...
}



Iterator模式的優點
1,實現功能分離,簡化容器接口。讓容器只實現本身的基本功能,把迭代功能委讓給外部類實現,符合類的設計原則。
2,隱藏容器的實現細節。
3,爲容器或其子容器提供了一個統一接口,一方面方便調用;另一方面使得調用者不必關注迭代器的實現細節。
4,可以爲容器或其子容器實現不同的迭代方法或多個迭代方法。

轉自:點擊打開鏈接
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章