定义
提供一个方法可以访问聚合对象,而不用知道这个对象的内部表示。
简介
作为一个java程序员,你可能使用过聚合对象,在java中他们被称为集合。集合也是一个对象,它作为一个容器来存储其他的对象,被存储的对象成为元素。基于集合石如何存储元素的,有不同类型的集合。例如一些集合允许重复的元素而一些不可以。ArrayList, LinkedList, HashMap,LinkedHashSet 就是java集合框架的一部分。像任何其他的对象一样,集合可以通过应用程序传递,或存储在其他集合对象中。
一个集合至少需要提供客户端方法来添加和移除元素。但更重要的是,它需要让客户遍历它存储的元素。集合类本身可以实现提供访问所需的功能并允许其元素遍历。但是这样做,集合的底层结构和实现将暴露给客户。这是一个坏的面向对象的设计原则,不遵循封装。此外,如果你回过头去重温solid设计原则,这将是明显的,实现元素访问和遍历操作的集合本身显然是违反单一职责原则。集合只负责充当存储元素的容器,任何其他职责,如元素访问和遍历不应该是它的一部分。
迭代器模式在处理聚合对象时解决这样的问题。这个模式所说的是聚合对象应该提供一种方法来访问它的元素,而不必暴露它的内部结构。为了完成模式的目的,我们需要分离存储在聚合对象中的元素的访问和遍历的职责,并将其分配给另一个对象,该对象称为迭代器。迭代器跟踪元素,可以进行不同类型的你想完成的遍历。将迭代器对象与聚合对象解耦是很重要的,因此可以重用它来遍历其他类型的聚合对象。您可以以这样一种方式设计您的程序,客户端请求其迭代器的聚合对象,而聚合对象返回带有初始化元素的数据结构的迭代器。然后客户端使用迭代器遍历元素。
下图显示了迭代器模式的基本通信流程。
参与者
考虑这样一种情况,你需要在应用程序中存储GoF设计模式的信息,其他组件将使用它打印信息或则和把这些信息发布到网页上。按照这种要求我们可以塑造一个DesignPattern类来表示设计模式。接下来,我们为这个集合定义一个接口,接口存储DesignPattern对象。让我们叫它PatternAggregate。我们可以建立一个具体的类,命名为PatternAggregateImpl 实现了PatternAggregate。这个类的对象将负责存储DesignPattern元素,创建它的迭代器。接下来,我们创建迭代器的接口为PatternIterator 并且声明遍历元素的方法。我们将在具体的子类PatternIteratorImpl实现这个方法。
在上面的例子中,我们总结下迭代器模式的参与者:Aggregate (PatternAggregate): 定义一个创建迭代器对象的接口
ConcreteAggregate (PatternAggregateImpl): 实现了创建迭代器对象,返回一个具体迭代器的实例
Iterator (PatternIterator): 迭代器定义访问和遍历元素的接口
ConcreteIterator (PatternIteratorImpl): 实现迭代器接口,在遍历时跟踪当前聚合对象中的位置
应用设计模式
DesignPattern.java对象,它的对象将会是存储在ConcreteAggregate中的元素
PatternAggregate.java
推荐下我自己的Java学习群:515675832,不管你是小白还是大牛,小编我都挺欢迎,不定期分享干货,包括我自己整理的一份2017最新的Java资料和零基础入门教程,欢迎初学和进阶中的小伙伴。
PatternAggregateImpl.java
PatternIterator.java
PatternIteratorImpl.java
PatternAggregateImplTest.java
UML
总结
J2se平台的集合框架使用了迭代器模式。它提供了Iterable接口,java.util包中的类实现了这个接口,并且返回了Iterator 对象来遍历集合中的元素。大部分情况下,这些集合类能够满足你的需要。
但是在企业级应用开发中,可能会需要实现定制化的集合。例如,在Spring MVC应用中,你可能需要一个集合来存储Employee 对象。当然,你可以使用内置的java集合类。但是,想象一下,要求还规定,集合应只存储有经理头衔的Employee。我们可以为此要求创建一个集合类。在创建类时,请记住应用程序的某些其他组件将需要遍历集合类的元素。现在,当您的设计工具包包含了迭代器模式时,将其置于工作中,遍历元素而不暴露集合的内部表示形式。Spring框架还扩展了迭代器模式通过 CompositeIterator类。该类实现了java SEIterator 接口,维护多个其它迭代器,这些迭代器顺序的被调用,直到迭代器完成他们的操作。