一、什么是迭代器模式
按照一定顺序对元素进行遍历
容器与迭代分开。提供一种方法按照一定顺序访问一个集合里面的元素,而又不暴露集合内部的细节.迭代器一般有起始点/下一个点/是否还有元素这几个方法.分离了集合对象的遍历行为,抽象出一个迭代器类来负责,既可以不暴露集合的内部结构,又可以让外部代码透明地访问集合内部数据.
UML图
Iterator: 迭代器抽象类,凡是迭代器应该具备这些操作功能,当前的,下一个,还有没有?
Aggreate: 聚合抽象类,想要实现迭代的聚合,就必须要有迭代器来操作这个集合,所以它得有一个创建迭代器的方法.
ConcreteIterator:具体的迭代器,实现抽象迭代器的功能,它的出现是要用来操作聚合的,所以关联聚合
ConcreteAggreate:具体聚合类,应是一个聚合的容器.
二、适用场景
需要按一定顺序遍历聚合元素的情况,可以有多种遍历方式,考虑使用迭代器.期待集合内部数据不被暴露,但又可操作.比如一串数组,比如一组对象,比如国家风景区.
三、优缺点
优点
实现了单一职责
数据与遍历分隔
遍历形式灵活可控
缺点
增加新的聚合类需要对应增加新的迭代器类
类的个数成对增加,这在一定程度上增加了系统的复杂性。
四、大话中的例子
上车买票的例子,不管是小菜还是大鸟 亦或是小偷 全都逃不出售票员的法眼,一个一个全都要买票。
一个迭代器抽象类,定义了当前元素、下一个元素、还有没有元素的方法,一个聚集抽象类定义了创建迭代器的方法。
具体的迭代器和具体的聚合就分别实现方法,具体迭代器 持有并依赖一个聚合对象,构造时即赋值。具体聚合类则定义一个容器list 或数组都可以, 实现抽象聚合的创建迭代器的方法,创建一个迭代器并把自己放进去。然后 集合类添加成员,添加好了,创建迭代器, 迭代器循环遍历操作。
五、我的例子
using System;
using System.Collections.Generic;
namespace IteratorMode
{
class Program
{
static void Main(string[] args)
{
ConcreteAggregate aggr = new ConcreteAggregate();
aggr[0] = "鸣人";
aggr[1] = "佐助";
aggr[2] = "23";
aggr[3] = 100;
aggr[4] = 170;
Iterator iterator = aggr.CreateIterator();
while (!iterator.IsDone())
{
Console.WriteLine(iterator.Current());
iterator.Next();
}
}
}
abstract class Iterator
{
public abstract object First();
public abstract object Next();
public abstract object Current();
public abstract bool IsDone();
}
class ConcreteIterator : Iterator
{
ConcreteAggregate concreteAggregate;
int point = 0;
public ConcreteIterator(ConcreteAggregate concreteAggregate)
{
this.concreteAggregate = concreteAggregate;
}
public override object Current()
{
return concreteAggregate[point];
}
public override object First()
{
return concreteAggregate[0];
}
public override bool IsDone()
{
return point >= concreteAggregate.Count ? true : false;
}
public override object Next()
{
object obj = null;
point++;
if (point < concreteAggregate.Count)
obj = concreteAggregate[point];
return obj;
}
}
abstract class Aggregate
{
public abstract Iterator CreateIterator();
}
class ConcreteAggregate : Aggregate
{
public int Count { get => listobj.Count; }
IList<object> listobj = new List<object>();
public override Iterator CreateIterator()
{
return new ConcreteIterator(this);
}
public object this[int index]
{
get => listobj[index];
set => listobj.Insert(index, value);
}
}
}
运行结果
PS:迭代器模式应该具有很多变型用法,这是一种特别常用的模式,以至于许多软件自身已经做了这个功能,foreach() 就是这个功能的展现。IEnumerator 这就是迭代器。