GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式是为容器而生。
对容器中元素的遍历,有两种方式:1)将遍历方法塞到容器对象中去;2)容器本身不提供遍历算法,让使用容器的人自己去实现去。
问题所在:方法一种容器承受了过多的功能,它不仅要负责自己“容器”内的元素维护(添加、删除等等),而且还要提供遍历自身的接口;而且由于遍历状态保存的问题,不能对同一个容器对象同时进行多个遍历。第二种方式却又将容器的内部细节暴露无遗。
迭代器模式的出现,很好的解决了上面两种情况的弊端
这里讲的就是java中迭代器的实现,以Java 的Collection API设计来看,在JDK 1.4时,iterator()方法是定义在Collection接口上,每个Collection的实现都会有iterator()方法,在 JDK5之后,iterator()方法定义在Iterable接口上,而Collection接口则继承了Iterable接口.如图所示.
因为对象的实现方式不同,所以一般iterator放在实现内部作为内部类实现。
此处举一个例子,包括collection接口,iterator接口,arrayList实现类:
collection接口:内涵iterator接口的iteartor()方法,对外提供;
public interfaceCollection {
voidadd(Object o);
intsize();
Iteratoriterator();
}
Iterator接口,对外提供hasNext,next两个方法;
public interfaceIterator {
booleanhasNext();
Objectnext();
}
collection的实现类,其中包括add,size,iterator方法的实现,并且iterator() 方法的返回一个arrayListIterator内部类的对象,对象提供hasNext,next两个方法,
public classArrayList implements Collection {
privateObject[] objects = new Object[10];
private intindex = 0;
publicvoid add(Object o) {
if(index == objects.length) {
Object[]newObjects = new Object[objects.length * 2];
System.arraycopy(objects,0, newObjects, 0, objects.length);
objects= newObjects;
}
objects[index]= o;
index++;
}
publicint size() {
returnobjects.length;
}
publicArrayListIterator iterator() {
returnnew ArrayListIterator(); // 如果是单例可以不用new,直接用就行
}
privateclass ArrayListIterator implements Iterator {
int currentIndex = 0;//内部类实现iterator
@Override
publicboolean hasNext() { //接口实现类需要提供的方法
if(currentIndex >= index)
returnfalse;
Else return true;
}
@Override
publicObject next() { //接口实现类需要提供的方法
Objecto = objects[currentIndex];
currentIndex++;
returno;
}}}
这是1.4的做法,将iterator放在collection中,作为一个属性,这里这个不是重点,重点是这种结构:每个collcetion的对象中包含一个用内部类实现iterator接口的对象,用来操作本类的读取!这种设计太巧妙了!!同时以后可以大胆的用内部类哈!
更好的操作时在封装一个foreach方法,itertor的操作做进一步封装,如strategy中的TextCharChange,本身只做封装而用;
最好是将其放在iterator内部类中,封装hasNext,和it,next两个方法!但是,因为内部需要对每个元素做处理,所以放在内部还是不太合适,可以放在要做处理的外面的类中,或者测试类中!
public static voidforeach(IterableString iterator) {
Iteratorit = iterator.iterator();
while(it.hasNext()) {
System.out.println(it.next());
//换成处理的语句!
}}
这种方法,相当于通过iterator()方法,把一个collection类中的对外提供操控这个类中的元素的接口,统一为iteartor对象,并提供hasnext,next两个方法进行真实的操作!
这个想法太好了,但是其实,本质上也是一种封装,对访问collecion对象的方法的封装!巧妙就在他的iterator()方法,返回的是一个iterator对象,这个对象有两个方法可以操作collection中的元素!方法返回一个对象!!
我觉得应该用处很大,但是现阶段还不知道能用在哪儿!