一、迭代器模式的介绍
迭代器是针对集合对象而生的,对于集合对象而言,必然涉及到集合元素的添加删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作也放在集合对象中,但这样的话,集合对象就承担太多的责任了,面向对象设计原则中有一条是单一职责原则,所以我们要尽可能地分离这些职责,用不同的类去承担不同的职责。迭代器模式就是用迭代器类来承担遍历集合元素的职责。
二、迭代器模式的定义和类图
迭代器模式提供了一种方法顺序访问一个聚合对象(理解为集合对象)中各个元素,而又无需暴露该对象的内部表示,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
既然,迭代器模式承担了遍历集合对象的职责,则该模式自然存在2个类,一个是集合类,一个是迭代器类。在面向对象涉及原则中还有一条是针对接口编程,所以,在迭代器模式中,抽象了2个接口,一个是集合接口,另一个是迭代器接口,这样迭代器模式中就四个角色了,具体的类图如下所示:
从上图可以看出,迭代器模式由以下角色组成:
迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口
具体迭代器角色(ConcreteIteraror):具体迭代器角色实现了迭代器接口,并需要记录遍历中的当前位置。
集合角色(Aggregate):聚合角色负责定义获得迭代器角色的接口
具体集合角色(ConcreteAggregate):具体聚合角色实现聚合角色接口。
三、迭代器模式的实现
介绍完迭代器模式之后,下面就具体看看迭代器模式的实现,具体实现代码如下:
using UnityEngine;
using System.Collections;
// 抽象集合类
public interface IListCollection
{
//获得迭代器
Iterator GetIterator();
}
// 迭代器抽象类
public interface Iterator
{
bool MoveNext();
object GetCurrent();
void Next();
void Reset();
}
// 具体集合类 , 聚合角色负责定义获得迭代器角色的接口
public class ConcreteList : IListCollection
{
int[] collection;
public ConcreteList()
{
collection = new int[] { 2, 4, 6, 8 };
}
public Iterator GetIterator()
{
return new ConcreteIterator(this);
}
public int Length
{
get { return collection.Length; }
}
public int GetElement(int index)
{
return collection[index];
}
}
// 具体迭代器类 , 实现了迭代器接口,并需要记录遍历中的当前位置
public class ConcreteIterator : Iterator
{
// 迭代器要集合对象进行遍历操作,自然就需要引用集合对象
private ConcreteList _list;
private int _index;
public ConcreteIterator(ConcreteList list)
{
_list = list;
_index = 0;
}
public bool MoveNext()
{
if (_index < _list.Length)
{
return true;
}
return false;
}
public object GetCurrent()
{
return (object)(_list.GetElement(_index));
}
public void Reset()
{
_index = 0;
}
public void Next()
{
if (_index < _list.Length)
{
_index++;
}
}
}
客户端调用程序:
using UnityEngine;
using System.Collections;
public class IteratorPatternInstance : MonoBehaviour
{
void Start ()
{
//迭代器
Iterator iterator;
//集合类
IListCollection list = new ConcreteList();
//从集合类中获取迭代器
iterator = list.GetIterator();
//对迭代器进行操作
while (iterator.MoveNext())
{
int i = (int)iterator.GetCurrent();
Debug.Log(i);
iterator.Next();
}
}
}
四、迭代器模式的适用场景
在下面的情况下可以考虑使用迭代器模式:
系统需要访问一个集合对象的内容而无需暴露它的内部表示。
系统需要支持对集合对象的多种遍历。
系统需要为不同的集合结构提供一个统一的接口。
五、迭代器模式的优缺点
由于迭代器承担了遍历集合的职责,从而有以下的优点:
迭代器模式使得访问一个聚合对象的内容而无需暴露它的内部表示,即迭代抽象。
迭代器模式为遍历不同的集合结构提供了一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作
迭代器模式存在的缺陷:
迭代器模式在遍历的同时更改迭代器所在的集合结构会导致出现异常。所以使用foreach语句只能在对集合进行遍历,不能在遍历的同时更改集合中的元素。