迭代器模式
什么是迭代器模式?
迭代器模式 是一种 行为型设计模式(Behavioral Design Pattern),它提供一种方法来顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示。迭代器模式将遍历元素的责任从聚合对象转移到迭代器对象上,简化了聚合类,并使得可以用不同的方式遍历一个聚合对象。
现代高级编程语言(如 Java、C#、Python、JavaScript 等)已经将迭代器模式的核心功能 直接集成到语言语法或标准库中,开发者无需手动实现迭代器接口。
应用场景
- 需要统一遍历不同结构的聚合对象
- 需要支持多种遍历方式(正序、逆序、过滤等)
- 需要隐藏聚合对象的内部结构
- 需要为聚合对象提供统一的访问接口
优缺点
优点:
- 单一职责原则:将遍历逻辑与业务逻辑分离
- 开闭原则:可以新增迭代器而不修改聚合类
- 可以并行遍历同一聚合对象
- 可以暂停遍历并在之后继续
缺点:
- 对于简单集合可能过度设计
- 迭代器可能比直接遍历效率低
模式结构(角色组成)
角色 | 说明 |
---|---|
Iterator(迭代器接口) | 定义访问和遍历元素的接口,如 hasNext() 、next() 等方法。 |
ConcreteIterator(具体迭代器) | 实现迭代器接口,跟踪聚合对象中的当前位置。 |
Aggregate(聚合对象) | 定义创建迭代器对象,如 createIterator() 方法。 |
ConcreteAggregate(具体聚合) | 实现聚合接口,创建与之对应的具体迭代器。 |
代码示例
java
public interface Iterator<T> {
/**
* 是否存在下一个元素
*
* @return
*/
boolean hasNext();
/**
* 获取下一个元素
*
* @return
*/
T next();
/**
* 重置迭代器
*/
void reset();
/**
* 获取当前元素
*
* @return
*/
T currentItem();
/**
* 回滚到上一个元素
*/
void rollback();
/**
* 跳过当前元素
*/
void skip();
}
java
public class TodoItemIterator implements Iterator<TodoItem> {
private TodoItem[] items; // 待办事项数组
private int position; // 当前迭代位置
/**
* 构造函数
*
* @param items 待办事项数组
*/
public TodoItemIterator(TodoItem[] items) {
this.items = items;
this.position = 0;
}
/**
* 是否存在下一个元素
*
* @return
*/
@Override
public boolean hasNext() {
return position < items.length;
}
/**
* 获取下一个元素
*
* @return
*/
@Override
public TodoItem next() {
if(!hasNext()) {
throw new IndexOutOfBoundsException("No more items.");
}
return items[position++];
}
/**
* 重置迭代器
*/
@Override
public void reset() {
position = 0;
}
/**
* 获取当前元素
*
* @return
*/
@Override
public TodoItem currentItem() {
return items[position];
}
/**
* 回滚到上一个元素
*/
@Override
public void rollback() {
if (position > 0) {
position--;
}
}
/**
* 跳过当前元素
*/
@Override
public void skip() {
if (position < items.length) {
position++;
}
}
}
java
public abstract class Aggregate<T> {
protected T[] items;
protected int size;
public Aggregate(int capacity) {
this.size = 0;
this.items = initItems(capacity);
}
protected abstract T[] initItems(int capacity);
public void addItem(T item) {
if (size < items.length) {
items[size++] = item;
} else {
throw new ArrayIndexOutOfBoundsException("集合已满,无法添加新项。");
}
}
protected T[] getItems() {
return this.items;
}
public abstract Iterator<T> createIterator();
}
java
public class TodoList extends Aggregate<TodoItem> {
public TodoList(int capacity) {
super(capacity);
}
@Override
protected TodoItem[] initItems(int capacity) {
return new TodoItem[capacity];
}
@Override
public Iterator<TodoItem> createIterator() {
return new TodoItemIterator(this.getItems());
}
}
java
@Slf4j
public class Main {
public static void main(String[] args) {
// 创建待办事项
TodoList todoList = new TodoList(10);
todoList.addItem(new TodoItem("学习新技能", "学习Python编程", false));
todoList.addItem(new TodoItem("去超市", "购买生活用品", false));
todoList.addItem(new TodoItem("阅读书籍", "阅读《设计模式》", false));
todoList.addItem(new TodoItem("锻炼身体", "去健身房锻炼", false));
todoList.addItem(new TodoItem("学习编程", "完成Java课程", false));
todoList.addItem(new TodoItem("参加会议", "项目进展汇报", false));
todoList.addItem(new TodoItem("整理房间", "清理杂物", false));
todoList.addItem(new TodoItem("写博客", "分享编程经验", false));
todoList.addItem(new TodoItem("准备旅行", "规划下个月的旅行", false));
todoList.addItem(new TodoItem("看电影", "观看最新上映的电影", false));
Iterator<TodoItem> iterator = todoList.createIterator();
// 迭代并打印待办事项
while (iterator.hasNext()) {
TodoItem currentItem = iterator.currentItem();
log.info("标题: {}", currentItem.getTitle());
log.info("描述: {}", currentItem.getDescription());
log.info("是否完成: {}", currentItem.isCompleted());
log.info("--------------------");
TodoItem next = iterator.next();
if(next.getTitle().equals("整理房间")) {
// 如果当前任务是“学习编程”,则跳过
iterator.skip();
}
}
}
}