简介

迭代器模式(Iterator Pattern),是一种结构型设计模式。给数据对象构建一套按顺序访问集合对象元素的方式,而不需要知道数据对象的底层表示。

迭代器模式是与集合共存的,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像Java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,就可以引入迭代器模式,给我们的容器实现一个迭代器。

作用

  1. 可以提供多种遍历对象的方式,把元素之间查找调用的责任交给迭代器,而不是聚合对象。
  2. 分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

实现步骤

  1. 创建迭代器接口,定义hasNext()和next()方法
  2. 创建数据容器接口,用来创建迭代器
  3. 创建具体数据列表,实现数据容器接口,可以创建迭代器,内含数据列表对象
  4. 创建某种数据对象的迭代器,实现hasNext()以及next()方法,并且关联上数据对象列表

UML

Java代码

迭代器抽象接口

 

//Iterator.java 迭代器抽象接口,提供next和hasNext方法
public interfaceIterator {public booleanhasNext();publicObject next();
}

具体迭代器

//ObjectIterator.java 对象迭代器,实现了抽象迭代器的方法,聚合了对象列表
public class ObjectIterator implementsIterator {privateObjectList objectList;intindex;publicObjectIterator(ObjectList objectList) {this.objectList =objectList;
}

@Override
public booleanhasNext() {if (index <objectList.size()) {return true;
}
return false;
}

@Override
publicObject next() {if (this.hasNext()) {//返回数据对象提供的get方法,每访问一次则增加下标 return objectList.get(index++);
}
return null;
}
}

数据容器接口

//Container.go 创建抽象容器接口,创建一个迭代器
public interfaceContainer {publicIterator createIterator();
}

具体数据对象

//ObjectList.java 对象列表,是一种数据容器,可以创建一个迭代器
public class ObjectList implementsContainer {private Object[] objects = { "Google", "Apple", "Amazon"};

@Override
publicIterator createIterator() {
System.out.println(
this.getClass().getName() + "::createIterator() [获取迭代器 ObjectIterator]");//把当前对象传给迭代器 return new ObjectIterator(this);
}
public voidsetObjects(Object[] objects) {this.objects =objects;
}
public intsize() {returnobjects.length;
}
public Object get(intindex) {returnobjects[index];
}
}

测试调用

    /** 迭代器模式是给数据容器创建单独的迭代器,用来遍历里面的数据对象
* 数据容器和迭代器相互关联,外部通过迭代器来访问数据容器
* 通过这种方式由迭代器类来负责数据遍历,这样可以做到不暴露集合的内部结构
*/ int i = 0;
ObjectList objectList
= newObjectList();
objectList.setObjects(
new String[] { "Thomas", "Merry", "Jack", "Tony", "Jerry", "Joey"});//for循环迭代对象 for (Iterator iter =objectList.createIterator(); iter.hasNext();) {
String name
=(String) iter.next();
System.out.println(
"objectList[" + i + "] = " +name);
i
++;
}
//while循环迭代对象 Iterator iter2 =objectList.createIterator();
objectList.setObjects(
new Integer[] { 3, 5, 7, 9, 11});while(iter2.hasNext()) {
System.out.println(iter2.next());
}

Go代码

迭代器抽象接口

//Iterator.go 迭代器抽象接口,提供next和hasNext方法
type Iterator interface{
HasNext()
boolNext()string}

具体迭代器

//ObjectIterator.go 对象迭代器,实现了抽象迭代器的方法,聚合了对象列表
type ObjectIterator struct{//迭代器索引
  index int
  //聚合了数据对象
  objectList *ObjectList
}
func (o *ObjectIterator) HasNext() bool{if o.index <o.objectList.Size() {return true}return false}func (o *ObjectIterator) Next() string{ifo.HasNext() {//返回数据对象提供的get方法,每访问一次下标增加1位 item :=o.objectList.Get(o.index)
o.index
+= 1 returnitem
}
return ""}

数据容器接口

//Container.go 创建抽象容器接口,创建一个迭代器
type Container interface{
CreateIterator() Iterator
}

具体数据对象

//ObjectList.go 对象列表,是一种数据容器,可以创建一个迭代器
type ObjectList struct{//内部的数据结构
  objects []string}func (o *ObjectList) CreateIterator() Iterator {
fmt.Println(
"ObjectList::CreateIterator() [获取迭代器 ObjectIterator]")//创建迭代器实例,绑定新建当前对象 return &ObjectIterator{
objectList: o,
}
}
func (o *ObjectList) SetObjects(objects []string) {
o.objects
=objects
}
func (o *ObjectList) GetObjects() []string{returno.objects
}
func (o *ObjectList) Size() int{return len(o.objects)
}
func (o *ObjectList) Get(index int) string{returno.objects[index]
}

测试调用

    /** 迭代器模式是给数据容器创建单独的迭代器,用来遍历里面的数据对象
* 数据容器和迭代器相互关联,外部通过迭代器来访问数据容器
* 通过这种方式由迭代器类来负责数据遍历,这样可以做到不暴露集合的内部结构
*/ int i = 0;
ObjectList objectList
= newObjectList();
objectList.setObjects(
new String[] { "Thomas", "Merry", "Jack", "Tony", "Jerry", "Joey"});//for循环迭代对象 for (Iterator iter =objectList.createIterator(); iter.hasNext();) {
String name
=(String) iter.next();
System.out.
println("objectList[" + i + "] =" +name);
i
++;
}
//while循环迭代对象 Iterator iter2 =objectList.createIterator();
objectList.setObjects(
new Integer[] { 3, 5, 7, 9, 11});
while (iter2.hasNext()) {
System.out.
println(iter2.next());
}

C语言简版

#include <stdio.h>#include<stdlib.h>

//简单版C语言迭代器模式,自己构建List数据类型//数据结构,这里使用链表作为示例
structList
{
char *data;struct List *next;
};
//迭代器结构体 structIterator
{
struct List *current;int (*has_next)(struct Iterator *); //判断是否还有下一个元素 char *(*next)(struct Iterator *, char **); //获取下一个元素 };//判断是否还有下一个元素 int has_next(struct Iterator *iter)
{
return iter->current !=NULL;
}
//获取下一个元素 char *next(struct Iterator *iter, char **value)
{
if (iter->current ==NULL)
{
returnNULL;
}
*value = iter->current->data;
iter
->current = iter->current->next;return *value;
}
//初始化迭代器 void create_iterator(struct Iterator *iter, struct List *head)
{
iter
->current =head;
iter
->has_next = &has_next;
iter
->next = &next;
}
//遍历链表 void iterate_list(struct List *head)
{
structIterator iter;char *value;
create_iterator(
&iter, head);while (iter.has_next(&iter))
{
iter.next(
&iter, &value);
printf(
"\r\n %s", value);
}
printf(
"\n");
}
intmain()
{
printf(
"test start:\r\n");//构造一个链表 struct List *head = (struct List *)malloc(sizeof(structList));
head
->data = "Tom";
head
->next = (struct List *)malloc(sizeof(structList));
head
->next->data = "Jerry";
head
->next->next = (struct List *)malloc(sizeof(structList));
head
->next->next->data = "Max";
head
->next->next->next =NULL;//使用迭代器遍历链表 iterate_list(head);//释放链表内存 while (head !=NULL)
{
struct List *temp =head;
head
= head->next;free(temp);
}
return 0;
}

更多语言版本

不同语言实现设计模式:
https://github.com/microwind/design-pattern

标签: none

添加新评论