原文地址:http://dev.yesky.com/474/2168474.shtml
一、 引言
迭代这个名词对于熟悉Java的人来说绝对不陌生。我们常常使用JDK提供的迭代接口进行java collection的遍历:
Iterator it = list.iterator(); while(it.hasNext()){ //using “it.next();”do some businesss logic } |
而这就是关于迭代器模式应用很好的例子。
二、 定义与结构
迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。
从定义可见,迭代器模式是为容器而生。很明显,对容器对象的访问必然涉及到遍历算法。你可以一股脑的将遍历方法塞到容器对象中去;或者根本不去提供什么遍历算法,让使用容器的人自己去实现去吧。这两种情况好像都能够解决问题。
然而在前一种情况,容器承受了过多的功能,它不仅要负责自己“容器”内的元素维护(添加、删除等等),而且还要提供遍历自身的接口;而且由于遍历状态保存的问题,不能对同一个容器对象同时进行多个遍历。第二种方式倒是省事,却又将容器的内部细节暴露无遗。
而迭代器模式的出现,很好的解决了上面两种情况的弊端。先来看下迭代器模式的真面目吧。
迭代器模式由以下角色组成:
1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。
3) 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。
4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该容器的结构相关。
迭代器模式的类图如下:
![]() |
从结构上可以看出,迭代器模式在客户与容器之间加入了迭代器角色。迭代器角色的加入,就可以很好的避免容器内部细节的暴露,而且也使得设计符号“单一职责原则”。
注意,在迭代器模式中,具体迭代器角色和具体容器角色是耦合在一起的——遍历算法是与容器的内部细节紧密相关的。为了使客户程序从与具体迭代器角色耦合 的困境中脱离出来,避免具体迭代器角色的更换给客户程序带来的修改,迭代器模式抽象了具体迭代器角色,使得客户程序更具一般性和重用性。这被称为多态迭 代。
三、 举例
由于迭代器模式本身的规定比较松散,所以具体实现也就五花八门。我们在此仅举一例,根本不能将实现方式一一呈现。因此在举例前,我们先来列举下迭代器模式的实现方式。
1.迭代器角色定义了遍历的接口,但是没有规定由谁来控制迭代。在Java collection的应用中,是由客户程序来控制遍历的进程,被称为外部迭代器;还有一种实现方式便是由迭代器自身来控制迭代,被称为内部迭代器。外部 迭代器要比内部迭代器灵活、强大,而且内部迭代器在java语言环境中,可用性很弱。
2.在迭代器模式中没有规定谁来实现遍历算法。 好像理所当然的要在迭代器角色中实现。因为既便于一个容器上使用不同的遍历算法,也便于将一种遍历算法应用于不同的容器。但是这样就破坏掉了容器的封装 ——容器角色就要公开自己的私有属性,在java中便意味着向其他类公开了自己的私有属性。
那我们把它放到容器角色里来实现好了。这样迭代器角色就被架空为仅仅存放一个遍历当前位置的功能。但是遍历算法便和特定的容器紧紧绑在一起了。
而在Java Collection的应用中,提供的具体迭代器角色是定义在容器角色中的内部类。这样便保护了容器的封装。但是同时容器也提供了遍历算法接口,你可以扩展自己的迭代器。
好了,我们来看下Java Collection中的迭代器是怎么实现的吧。
//迭代器角色,仅仅定义了遍历接口 public interface Iterator { boolean hasNext(); Object next(); void remove(); } //容器角色,这里以List为例。它也仅仅是一个接口,就不罗列出来了 //具体容器角色,便是实现了List接口的ArrayList等类。为了突出重点这里指罗列和迭代器相关的内容 //具体迭代器角色,它是以内部类的形式出来的。AbstractList是为了将各个具体容器角色的公共部分提取出来而存在的。 public abstract class AbstractList extends AbstractCollection implements List { …… //这个便是负责创建具体迭代器角色的工厂方法 public Iterator iterator() { return new Itr(); } //作为内部类的具体迭代器角色 private class Itr implements Iterator { int cursor = 0; int lastRet = -1; int expectedModCount = modCount; public boolean hasNext() { return cursor != size(); } public Object next() { checkForComodification(); try { Object next = get(cursor); lastRet = cursor++; return next; } catch(IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } public void remove() { if (lastRet == -1) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch(IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } |
至于迭代器模式的使用。正如引言中所列那样,客户程序要先得到具体容器角色,然后再通过具体容器角色得到具体迭代器角色。这样便可以使用具体迭代器角色来遍历容器了……
四、 实现自己的迭代器
在实现自己的迭代器的时候,一般要操作的容器有支持的接口才可以。而且我们还要注意以下问题:
在迭代器遍历的过程中,通过该迭代器进行容器元素的增减操作是否安全呢?
在容器中存在复合对象的情况,迭代器怎样才能支持深层遍历和多种遍历呢?
以上两个问题对于不同结构的容器角色,各不相同,值得考虑。
五、 适用情况
由上面的讲述,我们可以看出迭代器模式给容器的应用带来以下好处:
1) 支持以不同的方式遍历一个容器角色。根据实现方式的不同,效果上会有差别。
2) 简化了容器的接口。但是在java Collection中为了提高可扩展性,容器还是提供了遍历的接口。
3) 对同一个容器对象,可以同时进行多个遍历。因为遍历状态是保存在每一个迭代器对象中的。
由此也能得出迭代器模式的适用范围:
1) 访问一个容器对象的内容而无需暴露它的内部表示。
2) 支持对容器对象的多种遍历。
3) 为遍历不同的容器结构提供一个统一的接口(多态迭代)。
六、 总结
迭代器模式在我们的应用中很广泛,希望本文能帮助你理解它。如有不对之处,还请不吝指正。
相关推荐
深入浅出Java设计模式之迭代器模式 _天极网
在深入浅出Java设计模式的高清中文PDF文件中,首先以一个生活化的例子引出了工厂模式的概念,介绍了工厂模式在面向对象编程中的重要性和实用性。文档详细讲解了20多种Java设计模式,并且在讲解的过程中包含了丰富的...
总结来说,Java设计模式中的迭代器模式提供了一种通用的方式来遍历容器中的元素,它隐藏了容器的内部结构,只暴露出必要的遍历接口,增强了代码的灵活性和可扩展性。在实际编程中,我们经常使用迭代器模式来遍历集合...
总的来说,深入浅出设计模式附书源码Java版源代码是一份宝贵的资源,对于想要提升Java设计能力的开发者来说,它提供了一个实践和学习设计模式的绝佳平台。通过实际操作和调试代码,你可以更好地理解和掌握这些模式,...
总结来说,Java中的迭代器模式是一种重要的设计模式,它分离了容器对象和遍历其元素的行为,提供了统一的接口供客户端代码使用,同时保护了容器的内部结构。这种模式在处理集合和序列数据时尤其有用,因为它允许我们...
总结来说,《深入浅出设计模式》是一本以易懂的方式介绍设计模式的优秀教材,结合书中给出的Java代码,无论你是Java开发者还是其他语言的程序员,都能从中受益,掌握设计模式这一核心的软件工程技能。通过学习本书,...
《深入浅出设计模式》是一本旨在帮助开发者理解和应用设计模式的经典书籍,它提供了C#和JAVA两种语言的源代码实现,使得学习者可以通过实际操作来加深对设计模式的理解。 1. **设计模式的基本概念**: 设计模式...
《深入浅出设计模式》是一本专为Java开发者编写的关于设计模式的中文教材,它旨在帮助读者理解和掌握设计模式这一编程领域的核心概念。设计模式是软件开发中的经验总结,是解决常见问题的有效模板,通过将成熟的设计...
《Java设计模式之禅》是一本深入浅出讲解设计模式的书籍,书中不仅包含23种经典设计模式的案例,还详细介绍了设计模式背后的思想和原则,适合初学者以及对设计模式有一定了解的程序员阅读。本书旨在帮助读者理解如何...
本资料"深入浅出Java 23种设计模式"旨在帮助开发者理解和应用这23种经典设计模式。 首先,我们要了解设计模式的三大类别:创建型模式、结构型模式和行为型模式。创建型模式关注对象的创建过程,如单例模式...
5.4.4Java实例——两个迭代器 211 5.4.5优势和缺陷 213 5.4.6应用情景 214 5.5MediatorPattern(中介者模式) 214 5.5.1定义 214 5.5.2现实示例——机场控制塔 215 5.5.3C#实例——聊天室 216 5.5.4Java实例...
《深入浅出设计模式(Java版)》这本书是面向Java开发者的一本全面解析设计模式的指南。它深入探讨了各种设计模式,旨在帮助读者更好地理解和应用这些模式来提高代码的可读性、可维护性和可扩展性。以下是该书可能...
《深入浅出设计模式样章》是一本专为软件开发者准备的指南,旨在帮助读者理解和掌握设计模式这一核心编程概念。设计模式是软件工程中经过时间验证、在特定情境下解决常见问题的有效方法,它提供了可重用的解决方案,...
《深入浅出设计模式》是一本旨在帮助读者理解和掌握设计模式的书籍,适合那些希望深入研究设计模式的IT从业者。这本书可能与《HEAD FIRST设计模式》相辅相成,通过不同的讲解方式来帮助读者更全面地理解这一领域。 ...
本电子书集合深入浅出地剖析了Java设计模式,旨在帮助开发者理解和应用这些模式,提升编程技能。 首先,让我们探讨“设计模式”的概念。设计模式并不是具体的代码或库,而是一种描述在特定编程环境中常见问题的最佳...
Java的23种设计模式是软件工程中非常重要的概念,它们是...以上是Java中23种设计模式的基本介绍,每一种模式都有其特定的适用场景,理解和熟练掌握这些设计模式,能够帮助开发者编写出更加灵活、可维护和可扩展的代码。
这本书不仅深入浅出地讲解了23种经典的设计模式,还提供了丰富的实践案例,旨在帮助读者提升软件设计的水平和代码的可维护性。 首先,我们要理解什么是设计模式。设计模式是软件工程中经过验证的、在特定情境下解决...