设计模式笔记_行为型_迭代器模式
1. 迭代器模式介绍
迭代器模式(Iterator Pattern)是一种行为设计模式,旨在提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。这个模式的主要目的是将集合的遍历与集合本身分离,使得用户可以遍历不同类型的集合对象。
类比场景:想象一下,你有一本书(集合),而你想要阅读这本书的每一页(元素)。迭代器就像一个书签,它帮助你从第一页开始,逐页翻阅,直到最后一页,而不需要直接去操控书本结构。
组成结构:迭代器模式通常包括以下几个组件:
- Iterator(迭代器接口):定义访问和遍历元素的接口,通常包含
next()
、hasNext()
等方法。 - ConcreteIterator(具体迭代器):实现迭代器接口,负责具体的遍历逻辑。
- Aggregate(聚合接口):定义创建迭代器的接口,通常包含一个方法
createIterator()
。 - ConcreteAggregate(具体聚合类):实现聚合接口,提供集合元素的存储。
优缺点分析
- 优点
- 单一职责原则:迭代器模式将集合元素的遍历逻辑与集合本身的存储分离。这对于复杂数据结构非常有用,比如树或图的遍历比较复杂,如果由客户端编写遍历算法会增加开发成本;如果将遍历算法放到集合容器类中,会增加容器代码的复杂性;此时将复杂的遍历算法单独抽出来放到迭代器类中是一个比较好的选择。
- 开闭原则:可以在不修改集合的情况下添加新的遍历算法。以图数据结构为例,业务默认使用的是深度优先遍历(使用DFSIterator迭代器),现在需要改用广度优先遍历算法,只需要新增一个广度优先遍历迭代器(BFSIterator),客户端将迭代器从DFSIterator修改为BFSIterator即可,其他代码都不用改动。
- 简化客户端代码:客户端可以使用同样的接口遍历不同的集合对象。迭代器提供了抽象的接口(Iterator),不同的集合对象实现各自的具体迭代器(链表迭代器LinkedIterator,图迭代器BFSIterator等),用户只需使用Iterator接口就能访问不同类型的集合对象。
- 局限性
- 额外开销:对于简单的集合结构,使用迭代器模式可能会增加不必要的开销。
- 复杂性:对于非常简单的集合,直接使用循环可能更加简单和高效。
适合场景:
- 当你需要对一个聚合对象进行多种不同的遍历方式。
- 当你需要为不同类型的聚合对象提供统一的遍历接口。
2. 代码演示
场景:模拟书本的阅读器(迭代器),顺序翻阅一本书(聚合类)的各个书页(元素)。
Iterator(迭代器接口):
// 迭代器接口:定义访问和遍历元素的接口,通常包含next()、hasNext()等方法
public interface Iterator<T> {//判断是否还有待遍历元素boolean hasNext();//游标移到下一个待遍历的元素,并返回当前元素T next();
}
ConcreteIterator(具体迭代器):
// 具体迭代器类:实现迭代器接口,负责具体的遍历逻辑。
public class BookIterator implements Iterator<String> {private final List<String> pages;private int position = 0;public BookIterator(List<String> pages) {this.pages = pages;}@Overridepublic boolean hasNext() {return position < pages.size();}@Overridepublic String next() {if (hasNext()) {// 返回当前元素,并移动到下一个元素return pages.get(position++);}return null;}
}
Aggregate(聚合接口):
// 聚合接口:定义创建迭代器的接口,通常包含一个方法createIterator()
public interface Aggregate<T> {Iterator<T> createIterator();
}
ConcreteAggregate(具体聚合类):
//具体聚合类:实现Aggregate接口以创建具体迭代器实例,提供集合元素的存储
public class BookCollection implements Aggregate<String> {private final List<String> pages = new ArrayList<>();public void addPage(String page) {pages.add(page);}@Overridepublic Iterator<String> createIterator() {return new BookIterator(pages);}
}
客户端代码:
public class IteratorClientDemo {public static void main(String[] args) {// 创建具体聚合对象BookCollection bookCollection = new BookCollection();bookCollection.addPage("page1:Introduction");bookCollection.addPage("page2:Chapter 1");bookCollection.addPage("page3:Chapter 2");Iterator<String> iterator = bookCollection.createIterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}
对应的类图: