初學設計模式(java版)一:行為型模式之--Iterator模式(迭代器模式)

可愛扎發表於2020-12-01

一句話概述Iterator模式

使用迭代器一個個的遍歷出集合中的元素

Iterator模式中四個主要的類和介面

Iterator(interface)

迭代器的介面。

首先,我們要知道迭代器的作用----遍歷集合的元素。所以其主要的兩個方法為hasNext、next。

hasNext用於判斷是否還有下一個元素、next用於取出當前元素,並且指向下一個元素(注意,這裡的next是獲取當前)

ConcreteIterator(class)

該類就是要實現Iterator,是一個確切的迭代器,實現hasNext、next方法

其內應該有個具體的集合,就是我們需要迭代的物件

該類還應該有個index變數,獲取當前的索引,用於判斷是否hasNext

Aggregate(interface)

集合的介面,實現該介面的表明就是一個確切的集合

該介面提供方法去建立一個Iterator

ConcreteAggregate(class)

實現Aggregate,一個確切的集合

其實現的createIterato方法建立對應的Iterator

UML圖

在這裡插入圖片描述

具體案例

使用書上的案例,從BookShelf中迭代出所有書籍

Aggregate

package com.cutezha.Iterator;

public interface Aggregate {
    public abstract Iterator createIterator();
}

Iterator

package com.cutezha.Iterator;

public interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();
}

Book

package com.cutezha.Iterator;

public class Book {
    private String name;
    public Book(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

BookShelf

書上的原內容是使用的陣列,我這裡使用ArrayList其實本來就是個集合了,只不過我多寫了個createIterator方法,建立相應的迭代器

package com.cutezha.Iterator;

import java.util.ArrayList;
import java.util.List;

public class BookShelf implements Aggregate{
    private List<Book> books;
    public BookShelf(){
        books = new ArrayList<Book>();
    }

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

    public void appendBook(Book book){
        books.add(book);
    }

    public int getLength(){
        return books.size();
    }

    @Override
    public Iterator createIterator() {
        return new BookShelfIterator(this);
    }
}

BookShelfIterator

bookshelf對應的迭代器,index代表的當前的索引

有一個bookshelf變數,就是確切的集合(這裡就可以用泛型了,可能Util下的iterator就是這樣實現的,我還沒看)

package com.cutezha.Iterator;

public class BookShelfIterator implements Iterator{

    private BookShelf bookShelf;
    private int index;

    public BookShelfIterator(BookShelf bookShelf){
        this.bookShelf = bookShelf;
        this.index = 0;
    }
    @Override
    public boolean hasNext() {
        if(index<bookShelf.getLength()){
            return true;
        }else {
            return false;
        }
    }

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

IteratorMain

進行測試

package com.cutezha.Iterator;

public class IteratorMain {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf();
        bookShelf.appendBook(new Book("book1"));
        bookShelf.appendBook(new Book("book2"));
        bookShelf.appendBook(new Book("book3"));
        bookShelf.appendBook(new Book("book4"));
        Iterator it = bookShelf.createIterator();
        while (it.hasNext()){
            Book book = (Book) it.next();
            System.out.println(book.getName());
        }
    }
}

思考與總結

為何要引入Iterator,直接遍歷不好嗎?

答:引入了迭代器模式,將迴圈與集合其實是分開了,我們發現在迭代器模式中,遍歷這個過程只涉及了Iterator的hasNext與next,也就是說,集合的改動與最終迴圈的語句是無關的。當其中的元件發生改變的時候,另外的元件不需要改變或者只需要少量的修改。

使用BookShelfIterator與BookShelf就可以達到目的了,為什麼還要Aggregate與Iterator這兩個介面?

答:關鍵詞,oop的多型性,不要忘了,我們當以物件導向的思想去程式設計,有了這兩個介面,就可以寫出不同的集合和迭代器。

最終彙總一下:

​ 迭代器模式的兩個關鍵:集合、迭代器

​ 集合:儲存的元素,建立其相應的迭代器

​ 迭代器:對其對應的集合進行遍歷

​ 也就是一開始的一句話概述:使用迭代器一個個的遍歷出集合中的元素

相關文章