简介
迭代器模式(Iterator Pattern):提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
- 迭代器将遍历功能从聚合对象中分离,更加方便的操作对象并且不用暴露内部结构。又称游标模式。
结构和实现
- 角色包括:
- 抽象迭代器:声明访问和遍历元素的接口。
- 具体迭代器:实现抽象迭代器,完成聚合对象的遍历,通常包含游标表示当前遍历的位置。
- 抽象聚合类:储存和管理对象的抽象类,声明创建迭代器的抽象方法。
- 具体聚合类:抽象聚合类的子类,创建具体迭代器。
- 迭代器模式结构。
- 接口设计时需要考虑全面,否则能修改接口,违背开闭原则。
- 可用抽象类实现抽象迭代器,提供接口方法的默认实现,这是缺省适配器模式的体现。
实例
- 销售管理系统中,需要对商品、顾客等信息进行遍历。抽象商品类中如果包含储存和管理数据,有包含遍历数据,则会违背单一职责原则,所以需要将遍历数据的功能提出到迭代器中。
- 商品迭代器。
public class ProductIterator implements AbstractIterator {
private ProductList productList;
private List products;
private int cursor1; //定义一个游标,用于记录正向遍历的位置
private int cursor2; //定义一个游标,用于记录逆向遍历的位置
public ProductIterator(ProductList list) {
this.productList = list;
this.products = list.getObjects(); //获取集合对象
cursor1 = 0; //设置正向遍历游标的初始值
cursor2 = products.size() -1; //设置逆向遍历游标的初始值
}
public void next() {
if(cursor1 < products.size()) {
cursor1++;
}
}
public boolean isLast() {
return (cursor1 == products.size());
}
public void previous() {
if (cursor2 > -1) {
cursor2--;
}
}
public boolean isFirst() {
return (cursor2 == -1);
}
public Object getNextItem() {
return products.get(cursor1);
}
public Object getPreviousItem() {
return products.get(cursor2);
}
}
内部类实现迭代器
- 具体迭代器和具体聚合类之间存在双向关系,其中的关联关系是为了获得聚合类中的存储的数据,从而在迭代器中操作。
- 将迭代器设计为聚合类的内部类,也可以访问到聚合类中的数据,同时也不需要关联具体聚合类。
优缺点和适用范围
- 优点:
- 可以以不同方式遍历一个聚合对象。使用不同的迭代器替换,改变遍历算法。
- 简化聚合类。将遍历的逻辑提取出来。
- 方便扩展。由于聚合类和迭代器的抽象层,扩展方便。
- 缺点:
- 系统复杂。增加聚合类需要对应的迭代器,类个数多。
- 抽象迭代器设计困难。需要考虑今后的扩展。
- 适用范围:
- 需要将对象访问和存储分离,无需暴露存储结构。
- 为一个聚合对象提供多种遍历方式。
- 为遍历不同的聚合结构提供统一的接口。