天天看點

疊代器模式

一、定義

疊代器(Iterator Pattern)模式的定義:又稱為遊标模式(Cursor Pattern),它提供一個對象來順序通路聚合對象中的一系列資料,而不暴露聚合對象的内部表示。疊代器模式可以為不同容器提供一緻的周遊行為,而不用關心容器内容元素組成 結構,疊代器模式是一種對象行為型模式 ;疊代器模式是通過将聚合對象的周遊行為分離出來,抽象成疊代器類來實作的,其目的是在不暴露聚合對象的内部結構的情況下,讓外部代碼透明地通路聚合的内部資料。現在我們來分析其基本結構與實作方法。

疊代器模式主要包含以下角色。

  1. 抽象聚合(Aggregate)角色:定義存儲、添加、删除聚合對象以及建立疊代器對象的接口。
  2. 具體聚合(ConcreteAggregate)角色:實作抽象聚合類,傳回一個具體疊代器的執行個體。
  3. 抽象疊代器(Iterator)角色:定義通路和周遊聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
  4. 具體疊代器(Concretelterator)角色:實作抽象疊代器接口中所定義的方法,完成對聚合對象的周遊,記錄周遊的目前位置。
疊代器模式

二、疊代器模式的案例

疊代器模式在我們生活中應用的得也比較廣泛,比如物流系統中的傳送帶,不管傳送的是什麼物品,都被打包成一個一個的箱子并且有一個統一的二維碼。這樣我們不需要關心箱子裡面是啥,我們在分發時隻需要一個一個檢查發送的目的地即可。還有将書放到書架中,并将書名按順序顯示而不用關心書的内容。這樣說可能大家還是覺得應用場景比較模糊,那麼就這樣說他的主要應用場景有三大類:

1、通路一個聚合對象的内容而無須暴露它的内部表示。

2、需要為聚合對象提供多種周遊方式。

3、為周遊不同的聚合結構提供一個統一的接口。

 其實這種設計模式我們在日常開發中基本不會用到,除非需要定制一個自己實作的資料結構對應的疊代器,否則,開源架構提供的 API 完全夠用。

/**抽象容器:Aggregate 接口
 * 所要便利的集合的接口。實作了該接口的類将成為一個可以儲存多個元素的集合,類似數組。
 * Aggregate接口中聲明的方法為iterator,作用為生成一個用于周遊的疊代器。
 * @param <E>
 */
public interface Aggregate<E>{
    boolean add(E element);

    boolean remove(E element);
    public abstract Iterator iterator();
}      
/**抽象疊代器:Iterator 接口
 *作用為周遊集合中元素,相當于循環語句中的循環變量(for(int i =0 ;i<arr.lenth;i++),
 * 具體實作一個順序周遊的疊代器。
 * hasNext() 方法判斷是否存在下一個,next()方法擷取下一個元素。
 * next方法在擷取元素的同時,要将計數器向下一個元素的計數加一。擷取的是目前元素,并指向下一個元素。
 */
public interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();
}      
public class Book {
    private String name ;
    public Book(String name){
        this.name=name;
    }
    public String getName(){
        return name;
    }
}      
/**
 * 具體聚合(ConcreteAggregate)
 * 實作Aggregate接口。實作了Aggregate接口的iterator方法。
  */
public class BookShelf implements Aggregate {

    private List<Book> books;


    public BookShelf() {
        this.books = new ArrayList<Book>();
    }

    public Book getBookAt(int index) {
        return books.get(index);
    }


    @Override
    public boolean add(Object element) {
        books.add((Book) element);
        return true;
    }
    public int getLength() {
        return books.size();
    }
    @Override
    public boolean remove(Object element) {
        return false;
    }

    /**
     * 方法傳回了周遊書架時要用的BookShelfIterator類作為書架的疊代器。當外部要周遊書架時會調用該方法。
     * @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;
    }

    public boolean hasNext() {
        if (index < bookShelf.getLength()) {
            return true;
        } else {
            return false;
        }
    }


    public Object next() {
        Book book = bookShelf.getBookAt(index);
        index++;
        return book;
    }
}      
public class Test {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf();
        bookShelf.add(new Book("A"));
        bookShelf.add(new Book("B"));
        bookShelf.add(new Book("C"));
        bookShelf.add(new Book("D"));
        Iterator it = bookShelf.iterator();
        while (it.hasNext()) {
            Book book = (Book) it.next();
            System.out.println(book.getName());
        }
    }
}      

Iterator模式中各角色的作用

Iterator(疊代器)

該角色責任定義按順序逐個周遊元素的接口。程式中,由Iterator接口扮演,定義了hasNext和next兩個方法。

Concretelterator(具體的疊代器)

該角色負責實作Iterator角色所定義的接口.該角色包含了周遊集合所必須的資訊。

Aggregate(集合)

該角色負責定義建立Iterator角色的接口。這個接口是一個方法會建立出一個,按照順序通路儲存在我内部元素的人。

ConcreteAggregate(具體集合)

該角色負責實作Aggregate角色所定義的接口。他會建立出具體的Iterator角色,也就是ConcreteIterator,也就是執行個體中的BookShelf。 

三、總結

優點:

  • 多态疊代:為不同的聚合結構提供一緻的周遊接口,即一個疊代接口可以通路不同的集合對象;
  • 簡化集合對象接口:疊代器模式将集合對象本身應該提供的元素疊代接口抽取到了疊代器中,使集合對象無須關心具體疊代行為;
  • 元素疊代功能多樣化:每個集合對象都可以提供一個或多個不同的疊代器,使的同種元索聚合結構可以有不同的疊代行為;
  • 解耦疊代與集合:疊代器模式封裝了具體的疊代算法,疊代算法的變化,不會影響到集合對象的架構

缺點:

  • 對于比較簡單的周遊(像數組或者有序清單),使用疊代器方式周遊較為繁瑣。
  • 在日常開發當中,我們幾乎不會自己寫疊代器。除非我們需要定制一個自己實作的資料結構對應的疊代器,不然正常的API足夠用了

git源碼:https://gitee.com/TongHuaShuShuoWoDeJieJu/design_pattern.git

這短短的一生我們最終都會失去,不妨大膽一點,愛一個人,攀一座山,追一個夢