专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Java教程 » java迭代器:深入浅出Java设计模式的迭代器模式 »正文

java迭代器:深入浅出Java设计模式的迭代器模式

来源: 发布时间:星期五, 2008年12月19日 浏览:2次 评论:0
、 引言   迭代这个名词对于熟悉Java人来说绝对不陌生我们常常使用JDK提供迭代接口进行java collection遍历: Iterator it = list.iterator; while(it.hasNext){  //using “it.next;”do some businesss logic }   而这就是有关迭代器模式应用很好例子    2、 定义和结构   迭代器(Iterator)模式又叫做游标(Cursor)模式GOF给出定义为:提供种思路方法访问个容器(container)对象中各个元素而又不需暴露该对象内部细节   从定义可见迭代器模式是为容器而生很明显对容器对象访问必然涉及到遍历算法你可以股脑将遍历思路方法塞到容器对象中去;或者根本不去提供什么遍历算法让使用容器人自己去实现去吧这两种情况好像都能够解决问题   然而在前种情况容器承受了过多功能它不仅要负责自己“容器”内元素维护(添加、删除等等)而且还要提供遍历自身接口;而且由于遍历状态保存问题不能对同个容器对象同时进行多个遍历第 2种方式倒是省事却又将容器内部细节暴露无遗   而迭代器模式出现很好解决了上面两种情况弊端先来看下迭代器模式真面目吧   迭代器模式由以下角色组成:   1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素接口   2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口并要记录遍历中当前位置   3) 容器角色(Container):容器角色负责提供创建具体迭代器角色接口   4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色接口——这个具体迭代器角色于该容器结构相关   迭代器模式类图如下: 从结构上可以看出迭代器模式在客户和容器的间加入了迭代器角色迭代器角色加入就可以很好避免容器内部细节暴露而且也使得设计符号“单职责原则”   注意在迭代器模式中具体迭代器角色和具体容器角色是耦合在——遍历算法是和容器内部细节紧密相关为了使客户从和具体迭代器角色耦合困境中脱离出来避免具体迭代器角色更换给客户带来修改迭代器模式抽象了具体迭代器角色使得客户更具般性和重用性这被称为多态迭代    3、 举例   由于迭代器模式本身规定比较松散所以具体实现也就 5花 8门我们在此仅举根本不能将实现方式呈现因此在举例前我们先来列举下迭代器模式实现方式   1.迭代器角色定义了遍历接口但是没有规定由谁来控制迭代在Java collection应用中是由客户来控制遍历进程被称为外部迭代器;还有种实现方式便是由迭代器自身来控制迭代被称为内部迭代器外部迭代器要比内部迭代器灵活、强大而且内部迭代器在java语言环境中可用性很弱   2.在迭代器模式中没有规定谁来实现遍历算法好像理所当然要在迭代器角色中实现既便于个容器上使用区别遍历算法也便于将种遍历算法应用于区别容器但是这样就破坏掉了容器封装——容器角色就要公开自己私有属性在java中便意味着向其他类公开了自己私有属性   那我们把它放到容器角色里来实现好了这样迭代器角色就被架空为仅仅存放个遍历当前位置功能但是遍历算法便和特定容器紧紧绑在起了   而在Java Collection应用中提供具体迭代器角色是定义在容器角色中内部类这样便保护了容器封装但是同时容器也提供了遍历算法接口你可以扩展自己迭代器   好了我们来看下Java Collection中迭代器是如何实现 //迭代器角色仅仅定义了遍历接口 public erface Iterator {  boolean hasNext;  Object next;  void remove; } //容器角色这里以List为例它也仅仅是个接口就不罗列出来了 //具体容器角色便是实现了List接口ArrayList等类为了突出重点这里指罗列和迭代器相关内容 //具体迭代器角色它是以内部类形式出来AbstractList是为了将各个具体容器角色公共部分提取出来而存在 public abstract AbstractList extends AbstractCollection implements List { …… //这个便是负责创建具体迭代器角色工厂思路方法 public Iterator iterator {   Itr; } //作为内部类具体迭代器角色 private Itr implements Iterator {   cursor = 0;   lastRet = -1;   expectedModCount = modCount;  public boolean hasNext {    cursor != size;  }  public Object next {   checkForComodication;   try {    Object next = get(cursor);    lastRet = cursor;     next;   } catch(IndexOutOfBoundsException e) {    checkForComodication;    throw NoSuchElementException;   }  }  public void remove {    (lastRet -1)    throw IllegalStateException;    checkForComodication;   try {    AbstractList.this.remove(lastRet);     (lastRet < cursor)     cursor--;    lastRet = -1;    expectedModCount = modCount;   } catch(IndexOutOfBoundsException e) {    throw ConcurrentModicationException;   }  }  final void checkForComodication {    (modCount != expectedModCount)    throw ConcurrentModicationException;  } }   至于迭代器模式使用正如引言中所列那样客户要先得到具体容器角色然后再通过具体容器角色得到具体迭代器角色这样便可以使用具体迭代器角色来遍历容器了……    4、 实现自己迭代器   在实现自己迭代器时候般要操作容器有支持接口才可以而且我们还要注意以下问题:   在迭代器遍历过程中通过该迭代器进行容器元素增减操作是否安全呢?   在容器中存在复合对象情况迭代器怎样才能支持深层遍历和多种遍历呢?   以上两个问题对于区别结构容器角色各不相同值得考虑    5、 适用情况   由上面讲述我们可以看出迭代器模式给容器应用带来以下好处:   1) 支持以区别方式遍历个容器角色根据实现方式区别效果上会有差别   2) 简化了容器接口但是在java Collection中为了提高可扩展性容器还是提供了遍历接口   3) 对同个容器对象可以同时进行多个遍历遍历状态是保存在每个迭代器对象中   由此也能得出迭代器模式适用范围:   1) 访问个容器对象内容而无需暴露它内部表示   2) 支持对容器对象多种遍历   3) 为遍历区别容器结构提供个统接口(多态迭代)    6、 整理总结   迭代器模式在我们应用中很广泛希望本文能帮助你理解它如有不对的处还请不吝指正

相关文章

读者评论

  • 共0条 分0页

发表评论

  • 昵称:
  • 内容: