1. 程式人生 > >[設計模式] - No.4 Iterator 模式

[設計模式] - No.4 Iterator 模式

Iterator 模式

本系列的文章主要是記錄設計模式的學習過程,圍繞《圖解設計模式》和我自身對於設計模式的理解。在文章中出現的程式碼多為《圖解設計模式》這本書中的程式碼。書中一共包含23個設計模式,這篇文章作為這個系列的第一篇文章。由於《圖解設計模式》這本書內容十分簡單,非常適合入門,如果對於設計模式想要進一步地研究,可以參閱一些其他書籍。

Iterator模式是一種非常簡單的設計模式,其設計出來的目的就是在不知道類具體內部實現的前提下,對這個類的集合中的元素進行一個一個的訪問。當我們對集合物件增加一種新迭代或者儲存方式的時候,並不需要修改對該集合物件訪問的程式碼,只需要增加對應的迭代器即可。

接下來,我們通過書中的一個例子來簡單的看一下什麼是迭代器模式:

首先,我們宣告一個Book類,這個類儲存書的一些資訊:

public class Book {

    private String bookName;

    public Book(String bookName) {
        this.bookName = bookName;
    }

    public String getBookName() {
        return bookName;
    }

    @Override
    public String toString
() { return "本書名稱叫 " + this.getBookName(); } }

接下來,我們宣告一個介面Aggregate.java,這個介面內部有一個函式,該返回一個迭代器。實現該介面表示將該類宣告為可以遍歷的集合,並可以獲得遍歷該類的迭代器。

import java.util.Iterator;

public interface Aggregate {
    Iterator iterator();
}

我們有一個BookShelf類,並實現上述的介面。其意義為一個書架可以被遍歷,並且我們能夠返回遍歷的迭代器

import java.
util.Iterator; import java.util.List; public class BookShelf implements Aggregate { private Book [] books; private int last; public BookShelf(int shelfSize){ this.books = new Book[shelfSize]; this.last = 0; } public void appendBook(Book book){ this.books[last] = book; last++; } public Book getBookAt(int i ){ return books[i]; } public int getLength(){ return last; } @Override public Iterator iterator() { return new BookShelfIterator(this); } }

注意到,在最後的iterator()函式中,我們返回了一個BookShelfIterator,也就是說,我們按照這個迭代器中實現的方式進行遍歷BookShelf

BookShelfIterator

import java.util.Iterator;

public class BookShelfIterator implements Iterator {

    private BookShelf bookShelf;
    private int cursor;

    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
    }

    @Override
    public Object next() {
        Book book = bookShelf.getBookAt(cursor);
        cursor++;
        return book;
    }

    @Override
    public boolean hasNext() {
        return cursor<bookShelf.getLength();
    }
}

Main.java對集合進行遍歷

import java.util.Iterator;

public class Main {

    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(5);
        bookShelf.appendBook(new Book("哈利波特"));
        bookShelf.appendBook(new Book("設計模式"));
        bookShelf.appendBook(new Book("故事會"));
        bookShelf.appendBook(new Book("情感分析"));

        Iterator iterator = bookShelf.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

當我們的BookShelf儲存形式更改,或者我們的遍歷的順序更改時,我們不需要修改集合遍歷這部分程式碼,只需要增加對應的迭代器即可。

上面這段程式碼和《圖解設計模式》中的程式碼幾乎一樣,我在某些細節地方做了修改。同時,在BookShelf中,我是用的是普通陣列進行儲存的,而沒有使用ArrayList等容器,是為了讓大家更清晰的看到迭代器模式的工作方式。

一個迭代器模式的類圖如下所示:

在這裡插入圖片描述

  • Aggregate(集合)

    該角色負責定義建立Iterator角色的介面

  • ConcreteAggregate(具體的集合)

    負責實現Aggregate角色所定義的介面。在這個例子中,由BookShelf扮演,他實現了iterator()的方法,並返回第一個訪問該集合的迭代器

  • Iterator(迭代器)

    Iterator主要負責定義按順序遍歷元素的介面API,例如next()hasNext()等方法

  • ConcreteIterator(具體的迭代器)

    實現Iterator角色所定義的介面,實現具體的next()hasNext()方法

應用了迭代器設計模式的好處就是,我們不需要知道集合儲存元素的方式,即可對集合進行遍歷。如果以後集合BookShelf中儲存的陣列改為ArrayList或者其他的容器型別,我們只需要新增一種新的對應這種儲存方式的迭代器實現即可。