设计模式之迭代器模式
2013-09-07 09:52
411 查看
1.迭代器模式的意图
让客户端类可以顺序访问集合元素。
2.迭代器模式在JAVA中的应用
这个模式在java的类库中已经实现了,在java中所有的集合类都实现了Conllection接口,而Conllection接口又继承了Iterable接口,该接口有一个iterator方法,也就是所以的集合类都可以通过这个iterator方法来转换成Iterator类,用Iterator对象中的hasnext方法来判断是否还有下个元素,next方法来顺序获取。
3.模式解读
UML图
角色分析
集合(聚集抽象类):一个接口,规定了具体集合需要实现的操作。
具体集合(具体聚集类):具体集合石实现了集合接口的一个实例,具体的集合按照一定的结构存储对象。具体集合应该有一个方法,该方法返回一个针对该集合的具体迭代器。
抽象迭代器:一个接口,规定了遍历具体集合的方法,比如next()方法。
具体迭代器:实现了迭代器接口的类的实例。具体迭代器在实现迭代器接口所规定的遍历集合的方法时,比如next()方法,要保证首次调用将按着集合的数据结构找到该集合的一个对象,并且每当找到集合中的一个对象,立即根据该集合的存储结构得到待遍历的后继对象的引用,并保证一次调用next()方法可以遍历集合。
代码实现:
运行结果如下:
大鸟请买车票
小菜请买车票
行李请买车票
老外请买车票
公交内部员工请买车票
小偷请买车票
------------反向遍历---------------
小偷请买车票
公交内部员工请买车票
老外请买车票
行李请买车票
小菜请买车票
大鸟请买车票
4.适用场合
1)当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历时,就应该考虑用迭代器模式。
2)当需要对聚集对象有多种遍历方式时,可以考虑用迭代器模式。
3)迭代器模式在访问数组,集合,列表等数据时,尤其是数据库数据操作时,是非常普遍的应用,所以各种高级语言 都对它进行了封装,反而给人感觉此模式本身不太常用。
5.注意
在实例化一个迭代器时,应该考虑对其集合的遍历是否更改了集合的内容。单线程一般不会出现这种问题,但在多线程程序中,就需要确保对集合的访问是同步的,如用一个互斥对象来同步对集合的访问。
让客户端类可以顺序访问集合元素。
2.迭代器模式在JAVA中的应用
这个模式在java的类库中已经实现了,在java中所有的集合类都实现了Conllection接口,而Conllection接口又继承了Iterable接口,该接口有一个iterator方法,也就是所以的集合类都可以通过这个iterator方法来转换成Iterator类,用Iterator对象中的hasnext方法来判断是否还有下个元素,next方法来顺序获取。
3.模式解读
UML图
角色分析
集合(聚集抽象类):一个接口,规定了具体集合需要实现的操作。
具体集合(具体聚集类):具体集合石实现了集合接口的一个实例,具体的集合按照一定的结构存储对象。具体集合应该有一个方法,该方法返回一个针对该集合的具体迭代器。
抽象迭代器:一个接口,规定了遍历具体集合的方法,比如next()方法。
具体迭代器:实现了迭代器接口的类的实例。具体迭代器在实现迭代器接口所规定的遍历集合的方法时,比如next()方法,要保证首次调用将按着集合的数据结构找到该集合的一个对象,并且每当找到集合中的一个对象,立即根据该集合的存储结构得到待遍历的后继对象的引用,并保证一次调用next()方法可以遍历集合。
代码实现:
/** * 聚集抽象类 */ public abstract class Aggregate { // 创建迭代器 public abstract Iterator createIteraotr(); }
/** * 具体的聚集类,继承聚集抽象类Aggregate */ public class ConcreteAggregate extends Aggregate{ // 声明一个List泛型变量,用于存放聚合对象 private List<Object> items = new ArrayList<Object>(); @Override public Iterator createIteraotr() { return new ConcreteIterator(this); } // 返回集合总个数 public int count(){ return items.size(); } public List<Object> getItems() { return items; } public void setItems(List<Object> items) { this.items = items; } }
/** * 迭代器抽象类 */ public abstract class Iterator { // 开始对象 public abstract Object first(); // 下一个对象 public abstract Object next(); // 当前对象 public abstract Object currentItem(); // 是否到结尾 public abstract boolean isDone(); }
/** * 具体的迭代器类,继承迭代器抽象类Iterator */ public class ConcreteIterator extends Iterator{ // 定义一个具体的聚集对象 private ConcreteAggregate aggregate; private int current =0 ; // 初始化时将具体的聚集对象传入 public ConcreteIterator(ConcreteAggregate aggregate){ this.aggregate =aggregate; } @Override public Object currentItem() { // 返回当前的聚集对象 return aggregate.getItems().get(current); } @Override public Object first() { // 得到聚集的第一个对象 return aggregate.getItems().get(0); } @Override public boolean isDone() { // 判断当前是否遍历到结尾,到结尾返回true return current>=aggregate.count()?true:false; } @Override public Object next() { // 得到聚集的下一个对象 Object ref = null; current++; if(current<aggregate.count()){ ref = aggregate.getItems().get(current); } return ref; } }
/** * 反向遍历的具体的迭代器类,继承迭代器抽象类Iterator */ public class ConcreteIteratorDesc extends Iterator{ // 定义一个具体的聚集对象 private ConcreteAggregate aggregate; private int current =0 ; // 初始化时将具体的聚集对象传入 public ConcreteIteratorDesc(ConcreteAggregate aggregate){ this.aggregate =aggregate; current = aggregate.count()-1; } @Override public Object currentItem() { // 返回当前的聚集对象 return aggregate.getItems().get(current); } @Override public Object first() { // 得到聚集的第一个对象 return aggregate.getItems().get(aggregate.count()-1); } @Override public boolean isDone() { // 判断当前是否遍历到结尾,到结尾返回true return current<0?true:false; } @Override public Object next() { // 得到聚集的下一个对象 Object ref = null; current--; if(current>=0){ ref = aggregate.getItems().get(current); } return ref; } }
public class Main { public static void main(String[] args) { // 聚集对象(公交车) ConcreteAggregate a = new ConcreteAggregate(); // 对象集合(新上来的乘客) List<Object> items = new ArrayList<Object>(); items.add("大鸟"); items.add("小菜"); items.add("行李"); items.add("老外"); items.add("公交内部员工"); items.add("小偷"); a.setItems(items); // 迭代器对象 Iterator i = new ConcreteIterator(a); // 迭代器第一个对象(从第一个乘客开始) Object item = i.first(); while(!i.isDone()){ System.out.println(i.currentItem()+"请买车票"); i.next(); } System.out.println("------------反向遍历---------------"); //-----反向遍历------------------- Iterator iDesc = new ConcreteIteratorDesc(a); // 迭代器第一个对象(从最后一个乘客开始) Object item2 = iDesc.first(); while(!iDesc.isDone()){ System.out.println(iDesc.currentItem()+"请买车票"); iDesc.next(); } } }
运行结果如下:
大鸟请买车票
小菜请买车票
行李请买车票
老外请买车票
公交内部员工请买车票
小偷请买车票
------------反向遍历---------------
小偷请买车票
公交内部员工请买车票
老外请买车票
行李请买车票
小菜请买车票
大鸟请买车票
4.适用场合
1)当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历时,就应该考虑用迭代器模式。
2)当需要对聚集对象有多种遍历方式时,可以考虑用迭代器模式。
3)迭代器模式在访问数组,集合,列表等数据时,尤其是数据库数据操作时,是非常普遍的应用,所以各种高级语言 都对它进行了封装,反而给人感觉此模式本身不太常用。
5.注意
在实例化一个迭代器时,应该考虑对其集合的遍历是否更改了集合的内容。单线程一般不会出现这种问题,但在多线程程序中,就需要确保对集合的访问是同步的,如用一个互斥对象来同步对集合的访问。
相关文章推荐
- 设计模式——迭代器模式详解
- 深入理解JavaScript系列(35):设计模式之迭代器模式
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
- 极速理解设计模式系列:16.迭代器模式(Iterator Pattern)
- GoF23种设计模式之行为型模式之迭代器模式
- PHP设计模式之迭代器模式(Iterator)
- Net设计模式实例之迭代器模式(Iterator Pattern)
- 设计模式C#实现(四)——迭代器模式
- 设计模式之迭代器模式(Iterator)
- Java设计模式学习记录-迭代器模式
- 设计模式--迭代器模式
- c#设计模式系列:迭代器模式(Iterator)
- 设计模式学习笔记十六:迭代器模式
- 《模式——工程化实现及扩展》(设计模式C# 版)《迭代器模式 Iterator》——“自我检验" 参考答案
- 设计模式-迭代器模式和组合模式
- 设计模式之:迭代器模式(Iterator)
- 设计模式之14迭代器模式(笔记)
- 设计模式初探-迭代器模式
- 设计模式之迭代器模式
- Java设计模式-----Iterator迭代器模式