迭代器模式,行为设计模式之一。定义就是,提供一种方法顺序访问一个容器对象中的各个元素,而又不需要暴露该对象的内部数据存储的实现。
迭代器模式源于对数据集合的访问,将遍历的方法封装到数据集合中,或者不提供遍历方法由用户自己遍历。
以上两种方式都有弊端
- 封装在数据集合中,那数据集合似乎多了些功能,数据集合不仅要维护自身数据元素,还要对外提供遍历的接口方法,遍历状态下还不能对同一个数据集合进行多个遍历操作
- 不提公遍历方法,使用者自己实现,又会让容器的内部细节对外暴露
因此,迭代器模式就是为了解决这个问题而生的,在使用者和数据集合之间插入一个迭代器来解决上述弊端。
迭代器模式.png- Iterator:迭代器接口,负责定义、访问和遍历元素的接口
- ConcreteIterator:具体的迭代器,实现迭代器接口,并记录遍历的当前位置
- Aggregate:容器接口,负责创建具体迭代器角色的接口
- ConcreteAggregate:具体的容器类,具体迭代器和该容器相关联
迭代器接口
public interface Iterator<T> {
/**
* 返回当前位置元素并将位置移至下一位
*/
public T next();
/**
* 是否还有下一个元素
*
* @return true-有,false-没有
*/
public boolean hasNext();
}
具体的迭代器
public class ConcreteIterator<T> implements Iterator<T> {
private final List<T> list;
private int cursor = 0;
public ConcreteIterator(List<T> list) {
this.list = list;
}
@Override
public T next() {
T t = null;
if (hasNext()) {
t = list.get(cursor++);
}
return t;
}
@Override
public boolean hasNext() {
return cursor != list.size();
}
}
容器接口
public interface Aggregate<T> {
/**
* 添加一个元素
*
* @param obj 元素对象
*/
public void add(T obj);
/**
* 移除一个元素
*
* @param obj 元素对象
*/
public void remove(T obj);
/**
* 获取迭代器
*
* @return 迭代器对象
*/
public Iterator<T> iterator();
}
具体的容器类
public class ConcreteAggregate<T> implements Aggregate<T> {
private List<T> list = new ArrayList<>();
@Override
public void add(T obj) {
list.add(obj);
}
@Override
public void remove(T obj) {
list.remove(obj);
}
@Override
public Iterator<T> iterator() {
return new ConcreteIterator<>(list);
}
}
优点
- 封装性好,对外部的使用者来说可以以相同的API来获取不同结构的数据集合中的数据元素,不需要关心遍历算法,简化了遍历方式
- 便于扩展遍历方式,例如:可以创建一个正序迭代器同时还有一个倒序迭代器
缺点
- 对于简单的遍历,使用迭代器来遍历数据较为繁琐
看了ArratList
代码中的Iterator
主要的代码和上述是基本一致的,添加了更多的判断。而对于不同的数据结构Map
、Set
根据其不同的实现方式Iterator
的实现方式也各不相同。
迭代器模式,在数据结构中有广泛的使用,由于现在很多语言的API都提供了高效数据集合API,所以我们很少有需要去运用此模式,有兴趣的可以学习数据结构或者阅读源码来深入了解迭代器模式的实现。
「推荐」设计模式系列
设计模式(零)- 面向对象的六大原则
设计模式(一)- 单例模式
设计模式(二)- Builder模式
设计模式(三)- 原型模式
设计模式(四)- 工厂模式
设计模式(五)- 策略模式
设计模式(六)- 状态模式
设计模式(七)- 责任链模式
设计模式(八)- 解释器模式
设计模式(九)- 命令模式
设计模式(十)- 观察者模式
设计模式(十一)- 备忘录模式
设计模式(十二)- 迭代器模式
设计模式(十三)- 模板方法模式本文内容基于《Android源码设计模式解析与实践》
网友评论