迭代器模式
定义
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露对象的内部表示。为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口。总的来说,分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明的访问集合内部的数据。
当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候;需要对聚集有多种方式遍历时。
UML图
用例
上车买票
迭代器抽象类:用于定义得到开始对象、得到下一个对象、判断是否到结尾、当前对象等抽象方法,统一接口
abstract class Iterator{
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}
Aggregate聚集抽象类
abstract class Aggregate{
public abstract Iterator CreateIterator();
}
ConcreteIterator具体迭代器,继承Iterator
class ConcreteIterator extends Iterator{
// 定义了一个具体聚集对象
private ConcreteAggregate aggregate;
private int current = 0;
// 初始化时将具体的聚集对象传入
public ConcreteIterator(ConcreteAggregate aggregate){
this.aggregate = aggregate;
}
public override object First(){
return aggregate[0];
}
public override object Next(){
object ret = null;
current++;
if(current<aggregate.Count)
ret = aggregate[current];
return ret;
}
public override bool IsDone(){
return current >= aggregate.Count;
}
public override object CurrentItem(){
return aggregate[current];
}
}
ConcreteAggregate具体聚集类,继承Aggregate
class ConcreteAggregate extends Aggregate{
// 声明一个IList泛型变量,用于存放聚合对象,用ArrayList同样可以实现
private IList<object> items = new List<object>();
public override Iterator CreateIterator(){
return new ConcreteIterator(this);
}
public int Count{
get { return items.Count; }
}
/// 声明一个索引器
public object this[int index]{
get { return items[index]; }
set { items.Insert(index, value); }
}
}
客户端代码
static void Main(string[] args){
// 公交车,即聚焦对象
ConcreteAggregate a = new ConcreteAggregate();
// 新上来的乘客,即对象数组
a[0] = "大鸟";
a[1] = "小菜";
a[2] = "行李";
a[3] = "老外";
a[4] = "公交内部员工";
a[5] = "小偷";
// 售票员出场,先看好了上车的是哪些人,即声明了迭代器对象
Iterator i = new ConcreteIterator(a);
// 从第一个乘客开始
object item = i.First();
while(!i.IsDone()){
// 对面前的乘客告知请买票
Console.WriteLine($"{i.CurrentItem()} 请买票");
// 下一乘客
i.Next();
}
}
运行结果
大鸟 请买票
小菜 请买票
行李 请买票
老外 请买票
公交内部员工 请买票
小偷 请买票
从后向前的迭代器
class ConcreteIteratorDesc extends Iterator{
// 定义了一个具体聚集对象
private ConcreteAggregate aggregate;
private int current = 0;
/// 初始化时将具体的聚集对象传入
public ConcreteIteratorDesc(ConcreteAggregate aggregate){
this.aggregate = aggregate;
current = aggregate.Count - 1;
}
/// 得到聚焦的第一个对象
public override object First(){
return aggregate[aggregate.Count - 1];
}
// 得到聚焦的下一个对象
public override object Next(){
object ret = null;
current--;
if (current >= 0)
ret = aggregate[current];
return ret;
}
// 判断当前是否遍历到结尾,到结尾返回true
public override bool IsDone(){
return current < 0;
}
/// 返回当前的聚集对象
public override object CurrentItem(){
return aggregate[current];
}
}