Java设计模式--迭代器模式

1 Iterator Pattern 迭代器模式

目的:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示;
实现:把在元素之间游走的责任交给迭代器,而不是聚合对象。

1.迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据;
2.在同一个聚合上可以有多个遍历,往前、往后、或者双向;
3.由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

2 实现

代码场景:放一个书架上放书,然后对书本进行遍历;
书架相当于一个集合,每本书是集合中的元素。

2.1 代码实现

集合接口

/**
 * 集合接口
 */
public interface Aggregate {
    // 获取迭代器
    public Iterator iterator();
}

集合实现类:书架
提供了增加、删除、获取长度和获取迭代器的方法

/**
 * 具体的集合 书架
 */
public class BookShelf implements Aggregate {
    //集合的真实数据结构为数组 不对外展示
    private Book[] books;
    private int index = 0;

    // 好多集合类 都有默认值 超过默认值会扩容
    public BookShelf(int maxSize) {
        // 给数组指定长度
        books = new Book[maxSize];
    }
    // 添加书
    public void addBook(Book book) {
        books[index] = book;
        index++;
    }
    // 通过索引来获取指定的书
    public Book getBook(int index) {
        return books[index];
    }
    // 获取数组长度
    public int getLength() {
        return books.length;
    }
    // 获取书架迭代器
    @Override
    public Iterator iterator() {
        return new BookShelfIterator(this);
    }
}

集合元素类:书本

/**
 * 书本类
 */
public class Book {
    // 书名
    private String name;

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

迭代器接口
提供hasNext()、next()方法

/**
 * 迭代器接口
 */
public interface Iterator {
    // 是否存在下一个
    public boolean hasNext();

    // 获取下一本书
    public Book next();
}

迭代器实现类

/**
 * 书架迭代器
 */
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 (this.bookShelf.getLength() > index)
            return true;
        else
            return false;
    }

    @Override
    public Book next() {
        Book bookAt = bookShelf.getBook(index);
        index++;
        return bookAt;
    }
}

2.2 涉及角色

在迭代器模式结构图中包含如下几个角色:

Iterator(抽象迭代器):它定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法,例如:用于获取第一个元素的 first() 方法,用于访问下一个元素的 next() 方法,用于判断是否还有下一个元素的 hasNext() 方法,用于获取当前元素的 currentItem() 方法等,在具体迭代器中将实现这些方法。

ConcreteIterator(具体迭代器):它实现了抽象迭代器接口,完成对聚合对象的遍历,同时在具体迭代器中通过游标来记录在聚合对象中所处的当前位置,在具体实现时,游标通常是一个表示位置的非负整数。

Aggregate(抽象聚合类):它用于存储和管理元素对象,声明一个 createIterator() 方法用于创建一个迭代器对象,充当抽象迭代器工厂角色。

ConcreteAggregate(具体聚合类):它实现了在抽象聚合类中声明的 createIterator() 方法,该方法返回一个与该具体聚合类对应的具体迭代器 ConcreteIterator 实例。

2.3 调用

调用者:

public class Client {
    public static void main(String[] args) {
        // 去市场买了个书架
        BookShelf bs = new BookShelf(5);
        // 往书架上添加书
        bs.addBook(new Book("Java 从入门到放弃"));
        bs.addBook(new Book("MySQL 从删库到跑路"));
        bs.addBook(new Book("函数式编程 从入门到懵逼"));
        bs.addBook(new Book("算法概论 从入门到改行"));
        bs.addBook(new Book("僵尸生存法则"));

        // 获取书架的迭代器
        Iterator iterator = bs.iterator();

        // 通过迭代器来遍历书架
        while (iterator.hasNext()) {
            Book book = iterator.next();
            System.out.println(book.getName());
        }
    }
}

结果:

Java 从入门到放弃
MySQL 从删库到跑路
函数式编程 从入门到懵逼
算法概论 从入门到改行
僵尸生存法则

代码地址:点击跳转

参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.

猜你喜欢

转载自blog.csdn.net/weixx3/article/details/80153875