Java设计模式之迭代器模式

Java设计模式之迭代器模式

迭代子模式又称游标模式,是对象的行为模式。迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象;

Java聚集对象是实现了共同collection接口;

迭代子模式的结构

迭代子模式有两种实现方式,分别是白箱聚集与外禀迭代子和黑箱聚集与内禀迭代子。

白箱聚集与外禀迭代子

 如果聚集的接口提供了可以用来修改元素的方法,这个接口就是所谓的宽接口;

如果聚集对象为所有对象提供同一个接口,也就是宽接口的话,当然会满足迭代子模式对迭代子对象的要求。但是,这样会破坏聚集对象的封装。这种提供宽接口的聚集叫做白箱聚集。聚集对象对外界提供同样的宽接口;

由聚集自己实现迭代逻辑,并向外部提供适当的接口,使得迭代子可以从外部控制聚集元素的迭代过程,这样一来迭代子所控制的仅仅是一个游标而已,这种迭代子叫做游标迭代子。由于迭代子是聚集在聚集结构之外的,因此这样的迭代子又叫做外禀迭代子。

现在看一看白箱聚集与外禀迭代子的实现。一个白箱聚集向外界提供访问自己内部元素的接口(称作遍历方法),从而使外禀迭代子可以通过聚集的遍历方法实现迭代功能。

因为迭代的逻辑是由聚集对象本身提供的,所以这样的外禀迭代子角色往往仅仅保持迭代的游标位置。

迭代器模式涉及到以下几个角色:

抽象迭代子角色:此抽象角色定义出遍历元素的接口。

具体迭代子模式:此角色实现了Iterator接口,并保持迭代过程中的游标位置;

聚集角色:此抽象角色给出创建迭代子对象的接口。

具体聚集角色:实现了创建迭代子对象的接口,返回一个合适的具体迭代子实例;

客户端角色:持有对聚集及其迭代子对象的引用,调用迭代子对象的迭代接口,也有可能通过迭代子操作聚集元素的增加和删除;

 

黑箱聚集与内禀迭代子

如果一个聚集没有提供修改剧集元素的方法,这样的接口就是所谓的窄接口。

聚集对象为迭代子对象提供一个宽接口,而为其他对象提供一个窄接口。换言之,聚集对象的内部结构应当对迭代子对象公开,以便迭代子对象能够对聚集对象有足够的了解,从而可以进行迭代操作,但是聚集对象应当避免向其他的对象提供这些方法,因为其他对象应当经过迭代子对象进行这些工作,而不是直接操控对象。

在Java语言中,实现双重接口的办法就是将迭代子类设计成聚集类的内部成员类,也就是实现了抽象迭代子接口的具体迭代子类,同时聚集不向外界提供自己内部元素的方法;

主动迭代子和被动迭代子

主动迭代子和被动迭代子又称外部迭代子和内部迭代子;

主动迭代子:指的是由客户端来控制下一个元素的步骤,客户端会明显调用迭代子的next()等迭代方法,在遍历过程中向前进行;

被动迭代子:指的是由迭代子自己来控制下一个元素的步骤。因此,如果想要在迭代的过程中完成工作的话,客户端就需要把操作传递给迭代子,迭代子在迭代的时候会在每个元素上执行这个操作,类似于JAVA的回调机制;

静态迭代子和动态迭代子

静态迭代子由聚集对象创建,并持有聚集对象的一份快照,在产生后这个快照的内容就不再变化,客户端可以继续修改原聚集的内容,但是迭代子对象不会反映出聚集的新变化;

静态迭代子的好处是它的安全性和简易性,换言之,静态迭代子易于实现,不容易出现错误,但是由于静态迭代子将原聚集复制了一份,因此它的短处是对时间和内存资源的消耗;

动态迭代子与静态迭代子完全相反,在迭代子被产生之后,迭代子还保持着对聚集元素的引用,因此,任何对原聚集内容的修改都会在迭代子对象上反映出来。

完整的动态迭代子不容易实现,但是简化的动态迭代子并不难实现。我们遇到的迭代子就是简化的动态迭代子。

Fail Fast

如果一个算法开始之后,他的运算环境发生变化,使得算法无法进行必需的调整,这个算法就应当立即发出故障信号,即Fail Fast;

如果一个聚集对象的元素在一个动态迭代子的迭代过程中发生变化时,迭代过程会受到影响而不能自恰。这时候,迭代子就应当立即抛出一个异常,这个迭代子就是实现了Fail Fast功能的迭代子。

文章参考自:http://www.cnblogs.com/java-my-life/archive/2012/05/22/2511506.html

 

posted on 2018-10-12 09:55  yijiaxiong  阅读(149)  评论(0编辑  收藏  举报