[设计模式] - No.4 Iterator 模式

版权声明:Copyright©TJU YanMing https://blog.csdn.net/tjuyanming/article/details/84400396

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或者其他的容器类型,我们只需要添加一种新的对应这种存储方式的迭代器实现即可。

猜你喜欢

转载自blog.csdn.net/tjuyanming/article/details/84400396