Java設計模式學習記錄-迭代器模式

來源:互聯網
上載者:User
前言

這次要介紹的是迭代器模式,也是一種行為模式。我現在覺得寫部落格有點應付了,前陣子一天一篇,感覺這樣其實有點沒理解透徹就寫下來了,而且寫完後自己也沒有多看幾遍,上次在面試的時候被問到java中的I/O的各種實現用到了什麼設計模式,我愣是想半天沒想出來了,人家還給提示了我也沒想出來,最後還是面試官給出的答案,是裝飾模式,聽到答案後就恍然大悟了,前兩天剛看了裝飾模式,還寫下了I/O操作中的各種類都是用到了裝飾模式,後來想想兩方面原因造成的當時沒回答出來,一是面試時緊張就容易想不起來,二是對設計模式理解的還是不夠透徹。所以以後寧可寫部落格慢一些也要將自己寫的東西理解透徹了。

迭代器模式概念介紹

迭代器模式,又稱遊標模式。這種模式提供一種方法訪問一個容器物件中各個元素,而又不需要暴露該對象的內部細節。這種模式其實我們日常開發中也很常見,例如下面的情境:

        java.util.Iterator<String> it = list.iterator();                while (it.hasNext()){            //using "it.next();" do some business logic        }

這樣來理解簡單一些,下面還是通過具體的情境例子來實現迭代器模式。

舉例

一個書架上放著好幾本書,現在我想知道書架上都有哪些書,並且都把書名列印出來。那麼書架就可以具有迭代的功能,能把它存放的所有書籍都迭代出來。用代碼實現如下:

定義一個迭代器介面,包含檢測是否還有下一個元素的方法和獲得下一個元素的方法

/** * 迭代器介面 */public interface Iterator {    /**     * 檢測是否還有下一個元素     * @return     */    public abstract boolean hasNext();    /**     * 獲得下一個元素     * @return     */    public abstract Object next();}

定義含有迭代器對象的介面

/** * 只有實現此介面的才可以獲得迭代器對象 */public interface Aggregate {    /**     * 獲得迭代器對象     * @return     */    public abstract Iterator iterator();}

書籍類

/** * 書籍類 */public class Book {        //書籍名稱    private String name = "";    public Book(String name){        this.name = name;    }    /**     * 獲得書籍名稱     * @return     */    public String getName(){        return name;    }}

書架類

/** * 書架類 */public class BookShelf implements Aggregate{    private Book[] books;    private int last = 0;    public BookShelf(int maxSize){        this.books = new Book[maxSize];    }    /**     * 獲得書籍     * @param index     * @return     */    public Book getBookAt(int index){        return books[index];    }    /**     * 添加書籍     * @param book     */    public void appendBook(Book book){        this.books[last] = book;        last++;    }    /**     * 獲得書架上的書籍數量     * @return     */    public int getLength(){        return books.length;    }    /**     * 獲得書架迭代器對象     * @return     */    @Override    public Iterator iterator(){        return new BookShelfIterator(this);    }}

書架迭代器

/** * 書架迭代器 */public class BookShelfIterator implements Iterator {    private BookShelf bookShelf;    private int index;    public BookShelfIterator(BookShelf bookShelf){        this.bookShelf = bookShelf;        this.index = 0;    }    /**     * 檢測是否還有下一本書     * @return     */    @Override    public boolean hasNext() {        if(index<bookShelf.getLength()){            return true;        }else {            return false;        }    }    /**     * 返回下一本書     * @return     */    @Override    public Object next() {        Book book = bookShelf.getBookAt(index);        index++;        return book;    }}

測試類別

public class Client {    public static void main(String[] args) {        //建立一個書架        BookShelf bookShelf = new BookShelf(5);        //向書架中添加書籍        bookShelf.appendBook(new Book("深入理解Java虛擬機器"));        bookShelf.appendBook(new Book("Java編程思想"));        bookShelf.appendBook(new Book("高效能MySQL"));        bookShelf.appendBook(new Book("Effective Java 中文版"));        bookShelf.appendBook(new Book("資料結構與演算法分析Java語言描述"));        //獲得書架迭代器        Iterator iterator = bookShelf.iterator();        //迭代        while (iterator.hasNext()){            Book book = (Book) iterator.next();            System.out.println(book.getName());        }    }}

運行結果

深入理解Java虛擬機器Java編程思想高效能MySQLEffective Java 中文版資料結構與演算法分析Java語言描述

上面的這個例子就是實現了迭代器模式,可以看出來是在用戶端和容器間加入了迭代器,這樣就很好的避免容器內部細節的暴露,而且也使得設計符合“單一職責原則”。

迭代器模式的結構

迭代器模式主要由以下角色群組成

抽象迭代器角色(Iterator):抽象迭代器角色定義訪問和遍曆元素的介面。上面例子中的Iterator介面就是代表的這個角色。

具體迭代器角色(Concrete Iterator):具體迭代器角色要實現迭代器介面, 並要記錄遍曆中的當前位置。上面例子中BookShelfIterator類就是代表的這個角色。

容器角色(Aggregate):容器角色負責提供建立具體迭代器角色的介面。上面的例子中的Aggregate介面代表的就是這個角色。

具體容器角色(Concrete Aggregate):具體容器角色實現建立具體迭代器角色的介面,這個具體迭代器角色與該容器的結構相關。上面例子中書架類BookShelf

代表的就是這個角色。

總結

迭代器模式是一種使用頻率非常高的設計模式,通過引入迭代器可以將資料的遍曆功能從彙總對象中分離出來,彙總對象只負責儲存資料,而遍曆資料由迭代器實現完成。Java語言類庫中已經實現了迭代器模式,在實際開發中我們直接使用已經定義好的迭代器就可以了,像List、Set等集合都可以直接使用。

優點

1、它支援以不同的方式遍曆一個彙總對象,在同一個彙總對象上可以定義多種遍曆方式。替換迭代器就可以切換遍曆方法。

2、迭代器簡化了彙總類。彙總對象可以不用自己再提供遍曆方法。

3、在迭代器模式中由於引入了抽象層,增加新的彙總類和迭代器類都很方便,無須修改原有代碼,滿足“開閉原則”的要求。

缺點

1、由於迭代器模式將儲存資料和遍曆資料的職責分離,增加新的彙總類需要對應增加新的迭代器來,類的個數成對增加,這在一定程度上增加了系統的複雜性。

2、抽象迭代器設計難度相對較大,需要充分考慮到系統將來的擴充,,例如JDK內建迭代器Iterator就無法實現逆向遍曆,如果需要實現逆向遍曆,只能通過其子類ListIterator等來實現,而ListIterator迭代器無法用於操作Set類型的彙總對象。

適用情境

在以下情況可以考慮使用迭代器模式

1、訪問一個彙總對象的內容而無須暴露它的內部表示。將彙總對象的訪問與內部資料的儲存分離,使得訪問彙總對象時無須瞭解其內部實現細節。

2、需要為一個彙總對象提供多種遍曆方式。

3、為遍曆不同彙總結構提供統一的介面,該介面的實作類別中為不同的彙總結構提供不同的遍曆方式,而用戶端可以一致性的操作該介面。

 

 

 

 

想瞭解更多的設計模式請查看Java設計模式學習記錄-GoF設計模式概述。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.