设计模式-迭代器模式

一、概述

迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种方法来顺序访问一个聚合对象中的各个元素,而无需暴露其(聚合对象)内部的表示。
迭代器模式将遍历元素的职责从聚合对象中分离出来,并把这些职责放到一个独立的迭代器对象中。

二、前置知识

  • 聚合(Aggregate 接口):是所要遍历的集合的接口。在Java中,对应于Collection接口实现的Iterable接口。请添加图片描述
    实现了Iterable接口的类将成为一个可以保存多个元素的集合。
    Iterable接口内部实现了Iterator<T> iterator()接口,用于给实现了Iterable接口的类返回一个可用于迭代遍历该类内集合中元素的迭代器。请添加图片描述
  • 迭代器(iterator):访问和遍历集合元素的接口。该接口内实现了两个方法boolean hasNext()Object next()分别用于判断是否还存在下一个元素和获取下一个元素。请添加图片描述
  • 具体迭代器(ConcreteIterator):用于迭代某个集合的具体的迭代器
  • 具体聚合(ConcreteAggregate):实现Aggregate接口,并具体实现该接口中的Iterator iterator()方法,返回一个用于迭代遍历该集合的具体的迭代器实现。

三、迭代器的简易实现

  1. Aggregate接口
public interface Aggregate {
    Iterator iterator(); // 返回迭代器
}
  1. 具体聚合(ConcreteAggregate)
    书架类,里面封装了Book的集合,并实现了Aggregate接口和其iterator方法。

public class BookShelf implements Aggregate{
    List<Book> books;
    private int index;

    public BookShelf(){
        this.books = new ArrayList<>();
        this.index = 0;
    }
    
    public Book getBookAt(int index){
        return books.get(index);
    }
    public void appendBook(Book book){
        books.add(book);
        index++;
    }
    @Override
    public Iterator iterator() {
        return new BookShelfIteractor(this);
    }
}
  1. 迭代器(iterator)
public interface Iterator {
    boolean hasNext();

    Object next();
}
  1. 具体迭代器(ConcreteIterator)
    具体的迭代器BookShellIterator,实现了Iterator接口,专门用于迭代BookShell中的集合。
public class BookShelfIterator implements Iterator{

    BookShelf bookShelf;
    int last;

    public BookShelfIterator(BookShelf bookShelf){
        this.bookShell = bookShelf;
        this.last = 0;
    }
	// 判断是否还有元素未被迭代
    @Override
    public boolean hasNext() {
        if(last >= bookShelf.getLength()) return false;
        else return true;
    }
	//获取当前元素,并将指针下移一个位置
    @Override
    public Book next() {
        Book book = bookShelf.getBookAt(last);
        last++;
        return book;
    }
}
  1. 实体类
public class Book {
    private String name;

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

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

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                '}';
    }
}
  1. 测试代码
BookShell bookShell = new BookShell();
bookShell.appendBook(new Book("book1"));
bookShell.appendBook(new Book("book1"));
bookShell.appendBook(new Book("book1"));
Iterator iterator = bookShell.iterator();
while (iterator.hasNext()) {
    Book book = (Book) iterator.next();
    System.out.println(book);
}

Iteractor模式的类图

在这里插入图片描述

Iterator模式的要点

不管实现如何变化,都可以使用Iterator

具体来说,如果我们变更BookShelf类中的List<Book> booksBook[] books,即我们放弃用List而采用数组来存储Book,我们只需修改BookShelf中的getBookAt(idx)方法即可,不需要对BookoShelfIteractor类做出任何的修改。
也就是说BookShelfIterator类中的hasNextnext方法不依赖于BookShelf类,只负责调用getBookAt方法,而不需关注方法的具体实现。

四、总结

优点
  • 分离了集合对象的遍历行为:将遍历行为从集合对象中分离出来,这样集合对象可以专注于自身的数据存储,而不必关心遍历的细节。
  • 统一的遍历接口:为不同的集合对象提供一个统一的遍历接口,使得操作这些集合对象更加方便
  • 支持多种遍历方式:可以通过不同的迭代器实现不同的遍历方式。
缺点
  • 开销:为每个集合都定义一个迭代器类会增加系统的复杂性。
  • 额外的类:迭代器模式会增加额外的类,如果集合类型很多,迭代器类也会相应增多。
适用场景
  • 需要访问一个聚合对象的内容而无需暴露其内部表示时。
  • 需要为不同的聚合结构提供一个统一的遍历接口时。
  • 需要以不同的方式遍历一个聚合对象时。

通过迭代器模式,可以更加灵活和统一地处理不同类型的集合对象,增强代码的可维护性和可扩展性。

五、参考文献

《图解设计模式》

  • 34
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值