设计模式——Iterator模式实现研究

导读:软件设计模式是一种表达、记录和重用软件设计结构和设计经验的新方法,它对反复出现的设计结构的关键特征进行识别、抽象和命名,使重用成功设计和结构更加容易。本文介绍了软件设计模式的特点、描述方式以及在设计中使用模式带来的好处,并就迭代器(Iterator)模式在Java集合框架类(JavaCollectionFramework)中的典型实现为
例,说明此模式的实现方法以及利用此模式带来的软件扩充和使用的方便性。Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。
关键词:设计模式,Iterator模式,Java集合框架类

  0 引 言
  随着计算机网络和通信的快速发展和广泛应用,市场对企业的软件能力提出了近乎苛刻的要求,提高软件能力来化解软件危机已成为软件业的头等大事。。构件化和重用是200多年来工业化社会发展的成功经验,借鉴工业社会发展的成功经验,确定可行的软件工业化目标显得非常重要。构件化和重用是提高软件能力的必有之路。软件设计模式是一种表达、记录和重用软件设计结构和设计经验的新方法,它对反复出现的设计结构的关键特征进行识别、抽象和命名,使重用成功设计和结构更加容易。软件设计模式已经成为现代软件系统设计的重要研究对象。。本文介绍了软件设计模式的特点、描述方式以及在设计中使用模式带来的好处,并就迭代器(Iterator)模式在Java集合框架类(Java Collection Framework)中的典型实现为例,说明此模式的实现方法以及利用此模式带来的软件扩充和使用的方便性。
  1 设计模式
  设计模式的思想最初来源于建筑领域,但其中体现的思想也适用于其它领域,例如面向对象软件设计领域。设计模式关注的是特定设计问题及其解决方案,在每种模式中均描述一个设计问题和一个经过验证的、通用的解决方案,这个解决方案是对反复出现的设计结构进行识别和抽象得到的,它通常由多个对象组成,模式中不仅描述对象的设计,而且描述对象间的通信。
  一个设计模式有四个基本要素: 
  模式名称:一个助记名,它用一两个词来描述模式的问题、解决方案和效果。
  问题(problem):描述应该在何时使用该模式。
  解决方案(solution):描述设计的组成成分,它们之间的相互关系及各自的职责和协作方式。
  效果(consequences) 描述了模式应用的效果及使用模式
[论文网 www.uuubuy.com]应权衡的问题。模式效果包括它对系统的灵活性、扩充性或可移植性的影响,显式地列出这些效果对理解和评价这些模式很有帮助。
  根据所解决的问题不同,设计模式可分为创建型模式、结构型模式和行为模式三类。
  创建型模式都和如何有效地创建类的实例相关,这些模式使程序能够根据特定的情况创建特定的类。通过new来创建实例只能够在程序中生成固定的类。但是在很多情况下,程序需要根据不同的情况生成不同的类的实例,这就需要将实例的生成过程抽象到一个特殊的创建类中,由该类在运行时决定生成哪种类的实例。这样使得程序有更好的灵活性和通用性。
   结构型模式处理类和对象的组合,将类和对象组合起来,以构成更加复杂的结构。它又被划分为类模式和对象模式。类模式和对象模式之间的区别在于类模式通过继承关系来提供有效的接口;而对象模式通过对象合成或将对象包含在其它对象中的方式构成更加复杂的结构行为模式,
  行为类型的模式主要是那些处理对象之间通讯的模式。它描述类或对象的交互和职责分配,定义对象间的通信和复杂程序中的流控。本文涉及的迭代器(Iterator)模式就是一种行为模式。
  2 迭代器模式(Iterator Pattern)
  在面向对象的软件设计中,我们会遇到一类集合对象,这类集合对象的内部结构的实现可能差别很大,但是我们需要关心的只有两点:一是集合内部的数据存储结构,二是遍历集合内部的数据。单一职责原则是面向对象设计的一条重要原则,所以我们要尽可能的去分解这些职责,用不同的类去承担不同的职责。Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。
  迭代器使用的意图是提供一种方法顺序访问一个集合对象中的各个元素,而又不需要暴露该对象的内部细节。现在的电视机,使用[后一个]和[前一个]按钮切换频道。当按下[后一个]按钮时,将切换到下一个预置的频道。作为电视机的用户,当我们改变频道时,我们关心的不是具体的频道
,而是节目内容。如果对一个频道的节目不感兴趣,那么可以换下一个频道,而不需要知道它是具体是第几频道,图1给出了使用频道迭代器来选台的对象图。 图1使用选频器做例子的Iterator模式对象图 迭代器模式在客户与容器之间加入了迭代器角色。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向
客户端暴露集合的内部结构。。客户端自身不维护遍历集合的"指针",所有的内部状态(如当前元素位置,是否有下一个元素)都由Iterator来维护,客户端从不直接和集合类打交道,它总是控制Iterator,向它发送"向前","向后","取当前元素"的命令,就可以间接遍历整个集合。
  为了使客户程序从与具体迭代器耦合的困境中脱离出来,避免具体迭代器的更换给客户程序带来的修改,迭代器模式抽象了具体迭代器,使得客户程序更具一般性和重用性。
  Iterator模式结构图如图2所示下:
  
     图2 Iterator模式结构图
  从结构上可以看出,迭代器模式由以下角色组成:迭代器角色(Iterator),负责定义访问和遍历元素的接口;具体迭代器角色(Concrete Iterator),实现迭代器接口,并要记录遍历中的当前位置;容器角色(Container),负责提供创建具体迭代器角色的接口;具体容器角色(Concrete Container),实现创建具体迭代器角色的接口,它与该容器的结构相关。
  迭代器角色的加入,就可以很好的避免容器内部细节的暴露,而且也使得设计符合“单一职责原则”。具体迭代器角色和具体容器角色是耦合在一起的,即遍历算法是与容器的内部细节紧密相关的。
  3 Java类库中Iterator模式实现
  Java类库是设计模式的经典应用,在此以Java类库中的集合框架类(Java Collection Framework)为例来讨论Iterator模式的实现。
  在JavaCollection Framework的应用中,遍历的进程是由客户程序来控制的,这种实现方式被称为外部迭代器;它比由迭代器自身来控制迭代的内部迭代器更加灵活、强大。
  遍历算法的实现,表面上看应该在迭代器角色中实现。这样既便于在一个容器上使用不同的遍历算法,也便于将一种遍历算法应用于不同的容器。但是这样就要求容器角色公开自己的私有属性,从而破坏掉容器的封装性。所以遍历算法被放到容器角色里来实现。这样遍历算法便和特定的容器捆绑在一起,迭代器角色仅仅存放
[论文网 www.uuubuy.com]一个遍历的当前位置。这样做的另一个好处是对同一个容器对象,可以同时进行多个遍历。因为遍历状态是保存在每一个迭代器对象中的。在Java Collection Framework的应用中,提供的具体迭代器角色是定义在容器角色中的内部类,这样保护了容器的封装。同时容器也提供了遍历算法接口,便于扩展各自的迭代器。
  下面给出迭代器模式中的四个角色在JDK5.0中的JavaCollection Framework中所对应的代码片段,以此来分析迭代器模式如何在Java Collection Framework中实现,图3给出了我们要分析的基本类的类图:
  
   图3 Java Collection Framework中一个基本类图
  1)迭代器角色,接口Iterator,定义了遍历的接口, 
  代码片段1
  public interfaceIterator<E> {
  boolean hasNext();
  E next();
  void remove();
  }
  2)容器角色,接口List。
  3)具体容器角色,实现List接口并继承抽象类AbstractList的ArrayList类。
  4)具体迭代器角色,它是以抽象类AbstractList的内部类的形式出来的。抽象类AbstractList是为了将各个具体容器角色的公共部分提取出来而存在的。
  代码片段2所示的方法iterator()是负责创建具体迭代器角色的工厂方法。
  代码片段2:
  publicIterator<E> iterator() {
   return new Itr();
   }
  作为内部类的具体迭代器角色,其类图如图4所示,具体实现的代码如代码段3所示。
  
  图4 具体迭代器角色类图
  代码片段3: 
  private class Itrimplements Iterator<E> {
   intcursor = 0;
   intlastRet = -1;
   intexpectedModCount = modCount;
   publicboolean hasNext() {
  return cursor != size();
  }
   publicE next() {
  checkForComodification();
   try {

   E next = get(cursor)

; lastRet = cursor++; return next; } catch(IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } publicvoid remove() { if (lastRet == -1) throw new IllegalStat
eException();
  checkForComodification();
   try {
   AbstractList.this.remove(lastRet);
   if (lastRet < cursor) cursor--;
   lastRet = -1;
   expectedModCount = modCount;
   } catch(IndexOutOfBoundsException e) {
   throw new ConcurrentModificationException();
  }
   }
   finalvoid checkForComodification() {
   if (modCount != expectedModCount)
   throw new ConcurrentModificationException();
   }
  }
  迭代器模式的使用如下面的代码段4所示,客户程序要先得到具体容器角色,然后再通过具体容器角色得到具体迭代器角色。这样便可以使用具体迭代器角色来遍历容器。
  代码片段4
  List<E>
[论文网 www.uuubuy.com] list=new ArrayList <E>();
  Iterator it = list.iterator();
  while(it.hasNext()){
  it.next();//do some businesss logic 
  }
  4 总结
  迭代器模式在应用中使用非常广泛,它通过抽象出一个负责遍历行为的迭代器类,来达到既不暴露集合的内部结构,又可让外部代码透明的访问集合内部数据的目标。
  在实现自己的迭代器时,要操作的容器必须有相应的接口支持,通过在容器内增加相应的内部迭代器类来实现对具体容器的遍历,并且还要有创建具体迭代器角色的工厂方法。当然,不同结构的容器角色,其遍历的含义和实现也有较大差别,特别是当容器中存在复合对象或数据结构复杂时,如何进行深层遍历以及遍历的安全性都是值得关注的问题。

[参 考文 献]
[1](美)GoF。设计模式--可复用的面向对象软件的基础,机械工业出版社,2005. 
[2]深入浅出Java设计模式, http://www.cn-java.com.
[3].NET设计模式, http://www.cnblogs.com.
[4]龚波。java设计模式,人民邮电出版社,2007.
[5]饶一梅,王治宝,王秀峰。软件设计模式及其在Java类库中的典型实现。[J]计算机工程与应用,2002/4,P48—50.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436021.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】DCMTK 开源库的学习笔记2:直接操作dcm文件中像素数据的尝试

转自&#xff1a;https://blog.csdn.net/zssureqh/article/details/8785132 DCMTK官网给出了JPEG格式压缩的DCM文件解压缩的方法&#xff08;http://support.dcmtk.org/docs/mod_dcmjpeg.html&#xff09;&#xff0c;代码摘录如下&#xff1a; DJDecoderRegistration::regist…

R语言处理非线性回归模型C-D方程,使用R语言进行多项式回归、非线性回归模型曲线拟合...

对于线性关系&#xff0c;我们可以进行简单的线性回归。对于其他关系&#xff0c;我们可以尝试拟合一条曲线。曲线拟合是构建一条曲线或数学函数的过程&#xff0c;它对一系列数据点具有最佳的拟合效果。使用示例数据集#我们将使Y成为因变量&#xff0c;X成为预测变量#因变量通…

认识IL

1.要编译的代码如下&#xff1a; using System; using System.Collections.Generic; using System.Text; namespace HellowWorld { class Program { static void Main() { Console.Write("Hello World!"); } } } 2…

c语言之多线程函数,如何用C语言实现多线程

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼Windows操作系统&#xff0c;C语言实现多线程&#xff1a;#include #include DWORD APIENTRY ThreadOne ( LPVOID threadArg ){printf ( "线程开始啦&#xff0c;参数是&#xff1a;%s\n" , (char *)threadArg );return …

Iterator模式

Iterator模式的几种用法 在网络上看帖子时发现不少模式的初学者对Iterator模式的理解仅仅停留在从类库的容器类取得Iterator来遍历容器中的内容的程度。 因此在这里写几个例子&#xff0c;来加深大家对Iterator模式的理解。 对容器中元素的访问涉及到3个方面。 1&#xff0e;容…

【转】DCMTK开源库的学习笔记3:dcmtk文件中数据元的修改

转自&#xff1a;https://blog.csdn.net/zssureqh/article/details/8804736 dcm文件是医学领域DICOM3.0标准所对应的主要的文件格式。前两篇学习笔记中&#xff0c;学习了读取dcm文件的相关信息&#xff0c;如信息头MetaInformation元素、像素数据元素&#xff0c;只停留在了读…

设计模式C++实现 —— 外观模式、组合模式

外观模式应该是用的很多的一种模式&#xff0c;特别是当一个系统很复杂时&#xff0c;系统提供给客户的是一个简单的对外接口&#xff0c;而把里面复杂的结构都封装了起来。客户只需使用这些简单接口就能使用这个系统&#xff0c;而不需要关注内部复杂的结构。DP一书的定义&…

rsync的原理和安装使用及配制详解(三)(转)

5、示例脚本 这里这些脚本都是rsync网站上的例子&#xff1a; 1、每隔七天将数据往中心服务器做增量备份 #!/bin/sh# This script does personal backups to a rsync backup server. You will end up# with a 7 day rotating incremental backup. The incrementals will go# in…

单片机c语言控制显示器,单片机实现LCD液晶显示器控制原理..docx

摘 要LCD液晶显示已经是人机界面的关键技术。 本文对基于单片机的LCD夜晶显示器 控制系统进行了研究。首先在绪论中介绍了本课题的课题背景、 研究意义及完成的功能。本系统是以单 片机的基本语言C语言来进行软件设计&#xff0c;51的编程语言常用的有二种&#xff0c;一种是汇…

【转】DCMTK开源库的学习笔记4:利用ini配置文件对dcm影像进行归档

转自&#xff1a;https://blog.csdn.net/zssureqh/article/details/8846337 背景介绍&#xff1a; 医学影像PACS工作站的服务端需要对大量的dcm文件进行归档&#xff0c;写入数据库处理。由于医学图像的特殊性&#xff0c;每一个患者&#xff08;即所谓的Patient&#xff09;…

linux ( )含义,Linux的shell中$()、$[] 、${}分别是什么意思?

在bash中&#xff0c;$( )与 (反引号)都是用来作命令替换的。命令替换与变量替换差不多&#xff0c;都是用来重组命令行的&#xff0c;先完成引号里的命令行&#xff0c;然后将其结果替换出来&#xff0c;再重组成新的命令行。exp 1[rootlocalhost ~]# echo today is $(date &q…

导师评语(转)

星期一到了……小英在交完作业後&#xff0c;中午马上被老师叫去罚站&#xff0c;附加念500遍「我以後不敢编谎话欺骗老师了」。 why&#xff1f;为何这名老师要残忍的对待这名柔弱的小学生&#xff1f;我们来瞧瞧她的作文是怎麽写的…… ━━━━━━━━━━━━━━━━━━…

VxWorks平台下计算cpu的利用率

1、VxWorks的spyLib库提供的spy工具的实现原理。 Spy利用辅助定时器来产生中断&#xff0c;并且为每个任务维护一个计数器。然后记下被中断的任务&#xff0c;并且将该任务的计数器加一。经过一段时间后&#xff0c;每个任务的计数器反映了该任务占用CPU利用率的情况。很明显&a…

【转】DCMTK开源库类继承结构与DICOM3.0标准元素定义的对应关系图

转自&#xff1a;https://blog.csdn.net/zssureqh/article/details/9275271 最近由于课题需要&#xff0c;拿出来一些时间阅读了下DICOM3.0标准。在处理相关的DCM医学图像时使用了DCMTK开源库&#xff0c;废话不多说&#xff0c;直接贴图&#xff1a; 图一&#xff1a;DCMTK开…

c语言中用简易暗纹来输入密码,确定夫琅和费单缝衍射明、暗纹位置的不同教学方法的讨论...

崔红玲苏向英摘要&#xff1a;夫琅和费单缝衍射的明、暗纹位置及相应光强是波动光学中的重要部分&#xff0c;用不同的方法讲解效果不同。本文比较了惠更斯-菲涅耳原理定量积分法及半波带法得到的结论&#xff0c;表明在近似情况下&#xff0c;这两种方法都可以对其进行描述。关…

tickGet

tickGet&#xff08;&#xff09;返回的是从系统启动开始tick计数后的总的tick数目。 tick是啥&#xff0c;是“滴答”&#xff0c;它是一个数值量&#xff0c;本身不能代表时间。 如果说要知道tick增加一个代表多少时间的话&#xff0c;那就要看系统的时钟率了。 在Shell下…

C#控制台程序,发送邮件,可带附件

最近几天由于公司发送了大量内容相同的邮件,而被国外的反垃圾邮件组织列入了黑名单,致使很多客户收不到我们的邮件,客服接到投诉,而之前做的一个查询日志的小页面,因为某种原因,访问速度很慢,甚至这几天人一多,页面就总是超时.刚开始以为是程序问题或者是数据量比较大,但是程序…

【转】从零开始学图形学:10分钟看懂贝塞尔曲线

转自&#xff1a;https://zhuanlan.zhihu.com/p/344934774 引入 在画画的时候&#xff0c;你可能会遇到画曲线的情况。比如你想画一个肥宅的大肚子轮廓&#xff0c;此时你随手一画&#xff0c;发现不好看&#xff0c;感觉太鼓了&#xff0c;于是你只能重新画&#xff0c;再画一…

Linux重启网卡的方法

重启网卡的几种方法&#xff1a;一、network利用root帐户# service network restart二、ifdown/ifup# ifdown eth0# ifup eth0三、ifconfig# ifconfig eth0 down# ifconfig eth0 up

android webview url scheme,Android Webview ERR_UNKNOWN_URL_SCHEME错误

当我点击链接到mailto&#xff1a;adminikiyuzoniki.net时,我收到此错误&#xff1a;net: ERR_UNKNOWN_URL_SCHEME我试图添加一个if(url.startsWith(“mailto&#xff1a;”))条件,但它不起作用.这是我的MyWebViewClient方法&#xff1a;public class MyWebViewClient extends …