Iterator模式用来规格化对某一数据结构的遍历接口。
JDK中在Collection Framework中引入了Iterator接口,提供对一个Collection的遍历。每一个Collection类中都定义有从 Collection接口中继承而来的iterator()方法,来得到一个Iterator对象,我们称之为遍历器,Iterator接口很简单:
hasNext():用来判断在遍历器中是否还有下一个元素。
next():返回遍历器中的下一个元素。
remove():在被遍历的Collection类中删除最后被返回的那个对象。
我们就以最为常用的Vector为例,看看在Collection Framework中,Iterator模式是如何被实现的。在此之前,我们需要先了解一些Vector和Collection Framework的结构。
Collection接口作为这个Framework的基础,被所有其它的集合类所继承或者实现。对Collection接口,有一个基本的实现是抽象 类AbstractCollection,它实现了大部分与具体数据结构无关的操作。比如判断一个对象是否存在于这个集合类中的contains()方 法:
而这其中调用的iterator()方法是一个抽象方法,有赖于具体的数据结构的实现。但是对于这个containers()方法而言,并不需要知道具 体的Iterator实现,而只需要知道它所提供的接口,能够完成某类任务既可,这就是抽象类中抽象方法的作用。其它的在 AbstractCollection中实现的非抽象方法,大部分都是依赖于抽象方法iterator()方法所提供的Iterator接口来实现的。这 种设计方法是引入抽象类的一个关键所在,值得仔细领悟。
List接口继承Collection接口,提供对列表集合类的抽象;对应的 AbstractList类继承AbstractCollection,并实现了List接口,作为List的一个抽象基类。它对其中非抽象方法的实现, 也大抵上与AbstractCollection相同,这儿不再赘叙。
而对应于Collection的Iterator,List有其自己的ListIterator,ListIterator继承于Iterator,并添加了一些专用于List遍历的方法:
boolean hasPrevious():判断在列表中当前元素之前是否存在有元素。
Object previous():返回列表中当前元素之前的元素。
int nextIndex():
int previousIndex():
void set(Object o):
void add(Object o):
ListIterator针对List,提供了更为强劲的功能接口。在AbstractList中,实现了具体的iterator()方法和listIterator()方法,我们来看看这两个方法是如何实现的:
这儿的设计技巧和上面一样,都是使用抽象方法来实现一个具体的操作。抽象方法作为最后被实现的内容,依赖于具体的子类。抽象类看起来很像是一个介于接口和子类之间的一个东西。
从设计上来讲,有人建议所有的类都应该定义成接口的形式,这当然有其道理,但多少有些极端。当你需要最大的灵活性的时候,应该使用接口,而抽象类却能够 提供一些缺省的操作,最大限度的统一子类。抽象类在许多应用框架(Application Framework)中有着很重要的作用。例如,在一个框架中,可以用抽象类来实现一些缺省的服务比如消息处理等等。这些抽象类能够让你很容易并且自然的 把自己的应用嵌入到框架中去。而对于依赖于每个应用具体实现的方法,可以通过定义抽象方法来引入到框架中。
其实在老版本的JDK中也有 类似的概念,被称为Enumeration。Iterator其实与Enmeration功能上很相似,只是多了删除的功能。用Iterator不过是在 名字上变得更为贴切一些。模式的另外一个很重要的功用,就是能够形成一种交流的语言(或者说文化)。有时候,你说Enumeration大家都不明白,说 Iterator就都明白了。
Composite,Strategy和Iterator。Composite是一个结构性的模式,用来 协调整体和局部的关系,使之能够被统一的安排在一个树形的结构中,并简化了编程。Strategy模式与Bridge模式在结构上很相似,但是与 Bridge不同在于,它是一个行为模式,更侧重于结构的语义以及算法的实现。它使得程序能够在不同的算法之间自由方便的作出选择,并能够在运行时切换到 其他的算法,很大程度上增加了程序的灵活性。Iterator模式提供统一的接口操作来实现对一个数据结构的遍历,使得当数据结构的内部算法发生改变时, 客户代码不需要任何的变化,只需要改变相应的Iterator实现,就可以无缝的集成在原来的程序中。