三、设计模式
20、迭代器模式(Iterator Pattern)
20.1 定义
把在元素之间游走的责任交给迭代器,而不是聚合对象。简化了聚合的接口和实现,让聚合更专注在它所应该专注的事情上,这样做更加符合单一责任原则。
20.2 角色分配
- Iterator(抽象迭代器): 具体迭代器需要实现的接口,提供了游走聚合对象元素之间的方法
- ConcreteIterator(具体迭代器): 对具体的聚合对象进行遍历,每一个聚合对象都应该对应一个具体的迭代器。
- Aggregate(抽象聚合类): 存储和管理元素对象,声明了createIterator()用于创建一个迭代器对象,充当抽象迭代器工厂角色
- ConcreteAggregate(具体聚合类): 实现了在抽象聚合类中声明的createIterator(),该方法返回一个与该具体聚合类对应的具体迭代器ConcreteIterator实例。
20.3 结构图
20.4 代码实现
public interface MyIterator {
void first();
void next();
boolean hasNext();
boolean isFirst();
boolean isLast();
Object getCurrentObj();
}
public class ConcreteMyAggregate {
private List<Object> list = new ArrayList<>();
public List<Object> getList() {
return list;
}
public void setList(List<Object> list) {
this.list = list;
}
public void addObject(Object object) {
this.list.add(object);
}
public void removeObject(Object object) {
this.list.remove(object);
}
public MyIterator createIterator(){
return new ConcreteIterator();
}
//使用内部类定义迭代器,可以直接使用外部类的属性
private class ConcreteIterator implements MyIterator {
private int cursor; //定义游标用于记录遍历时的位置
[@Override](https://my.oschina.net/u/1162528)
public void first() {
cursor = 0;
}
[@Override](https://my.oschina.net/u/1162528)
public Object getCurrentObj() {
return list.get(cursor);
}
[@Override](https://my.oschina.net/u/1162528)
public boolean hasNext() {
if(cursor<list.size()){
return true;
}
return false;
}
[@Override](https://my.oschina.net/u/1162528)
public boolean isFirst() {
return cursor==0?true:false;
}
[@Override](https://my.oschina.net/u/1162528)
public boolean isLast() {
return cursor==(list.size()-1)?true:false;
}
@Override
public void next() {
if(cursor<list.size()){
cursor++;
}
}
}
}
20.5 优点
- 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合。
20.6 缺点
- 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
- 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
- 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心