深入浅出设计模式之迭代器模式.ppt_第1页
深入浅出设计模式之迭代器模式.ppt_第2页
深入浅出设计模式之迭代器模式.ppt_第3页
深入浅出设计模式之迭代器模式.ppt_第4页
深入浅出设计模式之迭代器模式.ppt_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

迭代器模式,本章内容,迭代器的引入迭代器模式迭代器模式的举例迭代器模式的理解迭代器模式的应用,迭代器模式的引入,数据结构介绍了很多容器性数据结构链表二叉树向量这些容器性数据结构包含多个元素,元素之间的逻辑关系不尽相同。,迭代器模式的引入,对于容器性数据结构,有时需要访问其中的每一个元素。由于每一个种数据结构的存储不同,访问每一个元素有差别链表二叉树向量,链表的遍历,Objecttemp=head;while(temp!=null)readtemp.value();temp=temp.next();,向量的遍历,intcurrent=0;while(currentvector.size()returnvector.get(current);current+;,二叉树的遍历(先序),if(root!=null)stack.push(root)while(!stack.isEmpty()BinaryTreeold=stack.pop();Objectresult=old.value();if(!old.right().isEmpty()压入右孩子if(!old.left().isEmpty()压入左孩子,例如常见的电视,可以定义一个遥控器的,每个工厂生产的电视机都有配套的遥控器,电视的频道为Item,每个遥控器都会有遍历的功能,用以遍历所有的频道。请大家举例:,存在的问题,用户需要了解每一种数据结构的内部元素结构的细节,这显然是不好的。我们能不能统一所有容器性数据结构的遍历呢?我们可以定义一个遍历所有数据结构的统一的接口。,迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。,定义可见,迭代器模式是为容器而生。很明显,对容器对象的访问必然涉及到遍历算法。你可以一股脑的将遍历方法塞到容器对象中去;或者根本不去提供什么遍历算法,让使用容器的人自己去实现去吧。这两种情况好像都能够解决问题。,然而在前一种情况,容器承受了过多的功能,它不仅要负责自己“容器”内的元素维护(添加、删除等等),而且还要提供遍历自身的接口;而且由于遍历状态保存的问题,不能对同一个容器对象同时进行多个遍历。第二种方式倒是省事,却又将容器的内部细节暴露无遗。,迭代器模式由以下角色组成:,1)迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。2)具体迭代器角色(ConcreteIterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。,3)容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。4)具体容器角色(ConcreteContainer):具体容器角色实现创建具体迭代器角色的接口这个具体迭代器角色于该容器的结构相关。,Iterator:迭代器定义访问和遍历元素的接口。ConcreteIterator(Controller):具体迭代器实现迭代器接口,对该聚合遍历时跟踪当前位置。Aggregate(Televation):聚合定义了创建相应迭代器对象的接口。ConcreteAggregate(HaierTV):具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。协作关系:ConcreteIterator跟踪聚合中的当前对象,并能够计算出待遍历的后继对象。,迭代器模式在客户与容器之间加入了迭代器角色。迭代器角色的加入,就可以很好的避免容器内部细节的暴露,而且也使得设计符合“单一职责原则”。,单一责任,一个类应该只有一个引起变化的原因管理自己的聚合遍历自己的元素内聚性:衡量一个类或模块紧密达到单一目的或责任的程度。高内聚低内聚高内聚易于维护,注意,在迭代器模式中,具体迭代器角色和具体容器角色是耦合在一起的遍历算法是与容器的内部细节紧密相关的。为了使客户程序从与具体迭代器角色耦合的困境中脱离出来,避免具体迭代器角色的更换给客户程序带来的修改,迭代器模式抽象了具体迭代器角色,使得客户程序更具一般性和重用性。这被称为多态迭代。,/迭代器角色,仅仅定义了遍历接口publicinterfaceIteratorbooleanhasNext();Objectnext();voidremove();,迭代器模式,迭代器是对象容器遍历行为的一种抽象将遍历行为与其他行为分离,从而无需暴露对象容器的内部结构隐藏遍历行为的内部实现,使用者使用统一的接口进行遍历对同一对象容器可支持不同的遍历方式迭代器接口:Iterator对象容器使用内部类实现该接口对象容器的使用者通过公有方法获得迭代器Java迭代器的使用迭代器返回的是对象引用的一个副本,没有创建对象实例副本迭代器是一次性消耗品,遍历完之后不可再用在遍历过程中,只能通过迭代器提供的方法改变容器类元素,通过其他途径会使得该迭代器不可再用,Java迭代器,Java迭代器接口基本用法,内部迭代器publicvoidremove(MenuComponentmenuComponent)thrownewUnsupportedOperationException();publicMenuComponentgetChild(inti)thrownewUnsupportedOperationException();publicStringgetName()thrownewUnsupportedOperationException();,publicStringgetDescription()thrownewUnsupportedOperationException();publicdoublegetPrice()thrownewUnsupportedOperationException();publicbooleanisVegetarian()thrownewUnsupportedOperationException();publicvoidprint()thrownewUnsupportedOperationException();,菜单项,publicclassMenuItemextendsMenuComponentStringname;Stringdescription;booleanvegetarian;doubleprice;publicMenuItem(Stringname,Stringdescription,booleanvegetarian,doubleprice)=name;this.description=description;this.vegetarian=vegetarian;this.price=price;,publicStringgetName()returnname;publicStringgetDescription()returndescription;publicdoublegetPrice()returnprice;publicbooleanisVegetarian()returnvegetarian;publicvoidprint()System.out.print(+getName();if(isVegetarian()System.out.print(v);System.out.println(,+getPrice();System.out.println(-+getDescription();,菜单,publicclassMenuextendsMenuComponentArrayListmenuComponents=newArrayList();Stringname;Stringdescription;publicMenu(Stringname,Stringdescription)=name;this.description=description;publicvoidadd(MenuComponentmenuComponent)menuComponents.add(menuComponent);,publicvoidremove(MenuComponentmenuComponent)menuComponents.remove(menuComponent);publicMenuComponentgetChild(inti)return(MenuComponent)menuComponents.get(i);publicStringgetName()returnname;publicStringgetDescription()returndescription;,publicvoidprint()System.out.print(n+getName();System.out.println(,+getDescription();System.out.println(-);Iteratoriterator=menuComponents.iterator();while(iterator.hasNext()MenuComponentmenuComponent=(MenuComponent)iterator.next();menuComponent.print();,客户如何使用,publicclassWaitressMenuComponentallMenus;publicWaitress(MenuComponentallMenus)this.allMenus=allMenus;publicvoidprintMenu()allMenus.print();,组合模式,组合模式违反了一个类,一个责任,而菜单组件:菜单菜单项组合模式我们采用了了违反类单一性原则的代价,换取,菜单和菜单项的统一。这就是一个设计模式的取舍问题。,组合迭代器,组合是一个递归对象,它的迭代比较复杂。刚才的print方法已经实现了部分,但其是内部迭代。外部迭代就更难了,必须要区分菜单和菜单项。菜单如何遍历菜单项如何遍历,菜单组件,publicabstractclassMenuComponentpublicabstractIteratorcreateIterator();,菜单,publicIteratorcreateIterator()returnnewCompositeIterator(menuComponents.iterator();,菜单项,publicIteratorcreateIterator()returnnewNullIterator();,组合迭代器,必须实现所有的组件内部的菜单项,包括子菜单和孙菜单里的菜单项。如何实现?,publicclassCompositeIteratorimplementsIteratorStackstack=newStack();publicCompositeIterator(Iteratoriterator)stack.push(iterator);publicvoidremove()thrownewUnsupportedOperationException();,publicObjectnext()if(hasNext()Iteratoriterator=(Iterator)stack.peek();MenuComponentcomponent=(MenuComponent)iterator.next();if(componentinstanceofMenu)stack.push(component.createIterator();returncomponent;elsereturnnull;,publicbooleanhasNext()if(stack.empty()returnfalse;elseIteratoriterator=(Iterator)stack.peek();if(!iterator.hasNext()stack.pop();returnhasNext();elsereturntrue;,publicclassNullIteratorimplementsIteratorpublicObjectnext()returnnull;publicbooleanhasNext()returnfalse;publicvoidremove()thrownewUnsupportedOperationException();,客户的使用,publicvoidprintVegetarianMenu()Iteratoriterator=allMenus.createIterator();System.out.println(nVEGETARIANMENUn-);while(iterator.hasNext()MenuComponentmenuComponent=(MenuComponent)iterator.next();tryif(menuComponent.i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论