0.《设计模式》摘录
-
意图:
一个聚合对象需要能够被遍历其中的元素,同时又不暴露它的内部结构。 -
多态迭代:
为遍历不同的聚合结构提供一个统一的接口
为所有的列表定义一个公共的操作接口AbstractList
为所有的迭代器类定义一个公共的接口Iterator
为每种具体的列表定义具体的迭代器,由列表对象负责创建相应的迭代器
可以在列表类中定义相应的工厂方法创建对应的迭代器
下面结构图就是多态迭代 -
适用性:
访问一个聚合对象的内容而无需暴露它的内部表示
支持对同一聚合对象的多种遍历
为遍历不同的聚合结构提供一个统一的接口(多态迭代) -
实现:
-
谁定义迭代算法:【下面的例子是外部迭代器】
关键的区别在于推动遍历的循环是在迭代器内部还是外部定义
外部迭代器:由使用迭代器的客户控制迭代过程,客户需要主动推进遍历的步骤,显式地向迭代器请求下一元素。
内部迭代器:客户向迭代器提交一个待执行的操作,迭代器将自动完成对聚合中元素的遍历并对每个元素实施这个操作。 -
谁定义遍历算法:
在迭代器中定义:
易于在相同的聚合上使用不同的迭代算法
改变迭代器即可
也易于在不同的聚合上重用相同的算法
同样的迭代器(例如同样的过滤标准)用在不同的聚合上
但如果遍历算法需要访问聚合对象的私有变量,这种方式会破坏聚合的封装性。
在聚合中定义:
在遍历过程中迭代器存储当前迭代的状态,这种迭代器称为游标,客户程序以游标为参数调用聚合的Next操作得到下一元素, Next操作同时修改游标的状态。
注意这里Next是聚合对象的方法
-
迭代器模式
-
定义
迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
-
结构图
-
Iterator迭代器抽象类:提供统一的接口
abstract class Iterator { public abstract Object First();//注意返回的是Object public abstract Object Next(); public abstract Object IsDone(); public abstract Object CurrentItem(); }
-
Concreteiterator:具体迭代器类,继承 Iterator
class ConcreteIterator extends Iterator { private ConcreteAggregate aggregate; private int current = 0; public Concreteiterator(ConcreteAggregate aggregate) { this.aggregate = aggregate; } 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 ? true : false; } public override object Currentitem() { return aggregate[current]; } }
-
Aggregate聚集抽象类:创建迭代器
abstract Class Aggregate { public abstract Iterator CreateIterator (); }
-
ConcreteAggregate :具体聚集类,继承 Aggregate
class ConcreteAggregate extends Aggregate { //声明一个List泛型变量,用于存放聚合对象 private List<object> items = new List<object>(); public override Iterator CreateIterator() { return new Concreteiterator(this); } //返回聚集总个数 public int getCount() { 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 (" {0}请买车票!", i .Currentitem ()); i.Next (); } Console.Read (); }
运行结果:
大鸟请买车票小菜请买车票
行李请买车票
老外请买车票
公交内部员工请买车栗
小偷请买车票
-
-
优点
迭代器(Iterator)模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
-
什么时候用迭代器模式?
-
当你需要访问一个聚集对象,而且不管这些対象是什么都需要遍历的时候。
举例:售票员不管你上来的谁,只要是来乘车的乘客,就必须要买票。
-
需要对聚集对象有多种方式遍历时
举例:售票员从车头到车尾来售票,也可以从车尾向车头来售票
-
为遍历不同的聚集结构提供如开始、下一个、是否结束、当前哪一项等统一的接口时
比如:不管乘客是什么,售票员的做法始终是相同的,都是从第一个开始,下一个是谁,是否结束,当前售到哪个人了,他每天都在做统一的操作。
-
-
为什么需要一个迭代器的抽象类,而不是只要具体类?
因为可以通过继承,实现对聚集多种方式遍历。