定义
提供一种可以顺序访问一个聚合对象中的各种元素的方法,同时又不暴露该对象的内部表示。
目的
遍历一个对象
优点
访问一个聚合数据,聚合数据不会暴露内部内容
缺点
会增加类的个数,增加系统复杂性
解释
在我们开发的过程中,经常要访问一个聚合对象中的各个元素,比如链表的遍历。我们在遍历链表时,通常是将链表的创建和遍历都放在同一个类中,但这种方式不利于程序的扩展,如果要更换遍历方法就必须修改程序源代码,这显然是违背了 “开闭原则”;
如果类中不提供遍历方法,直接将遍历方法由客户端自己实现是否可行呢?答案也是否定的,因为这样做会带来两个弊端:
- 暴露了聚合类的内部表示,使其数据不安全;
- 给客户端带来了麻烦。增加了负担;
所以为了解决这种情况,我们就需要用到迭代器模式了。它在客户端访问类与聚合类之间插入了一个迭代器,就可以将聚合对象与其遍历行为进行分离,同时也对客户端访问类隐藏了其内部细节,且满足“单一职责原则”和“开闭原则”,就像 Java 中的 Collection、List 等等都是迭代器模式的良好体现;
迭代器模式所包含的几个角色:
抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
实例
//迭代接口
public interface Iterator {
boolean hasNext();
Object next();
}
//容器接口
public interface Container{
Iterator getIterator();
}
//容器
public class NameContainer implements Container {
public String[] names = {"name1" , "name2" ,"name3" , "name4"};
@Override
public Iterator getIterator() {
return new NameIterator();
}
class NameIterator implements Iterator{
int index;
@Override
public boolean hasNext() {
if(index < names.length){
return true;
}
return false;
}
@Override
public Object next() {
if(this.hasNext()){
return names[index++];
}
return null;
}
}
}
//使用
NameContainer nameContainer = new NameContainer();
Iterator it = nameContainer.getIterator();
while(it.hasNext()){
String name = (String) it.next();
System.out.println(name);
}
Iterator接口,必须实现下一个 对象 和 是否有下一个对象。Container接口 需要返回一个实现Iterator接口的类。
在java中HashMap的内部类KeySet有Iterator,android中访问数据库有Cursor,都是是用了迭代器模式