以下内容出自:<<24种设计模式介绍与6大设计原则>>

  周五下午,我正在看技术网站,第六感官发觉有人在身后,扭头一看,我C,老大站在背后,赶忙站起来,

  “王经理,你找我?” 我说。
  “哦,在看技术呀。有个事情找你谈一下,你到我办公室来一下。” 老大说。
  到老大办公室,
  “是这样,刚刚我在看季报,我们每个项目的支出费用都很高,项目情况复杂,人员情况也不简单,我看着
  也有点糊涂,你看,这是我们现在还在开发或者维护的103 个项目,你能不能先把这些项目信息重新打印一份
  给我,咱们好查查到底有什么问题。”老大说。
  “这个好办,我马上去办”我爽快的答复道。
  很快我设计了一个类图,并开始实施:

类图非常简单,是个程序员都能实现,我们来看看简单的东西:

  1. package cn.mjorcen.iterator_pattern;
  2.  
  3. /**
  4. * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
  5. * all. 定义一个接口,所有的项目都是一个接口
  6. */
  7. public interface IProject {
  8. // 从老板这里看到的就是项目信息
  9. public String getProjectInfo();
  10. }

定义了一个接口,面向接口编程嘛,当然要定义接口了,然后看看实现类:

  1. package cn.mjorcen.iterator_pattern;
  2.  
  3. /**
  4. * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
  5. * all. 所有项目的信息类
  6. */
  7. public class Project implements IProject {
  8. // 项目名称
  9. private String name = "";
  10. // 项目成员数量
  11. private int num = 0;
  12. // 项目费用
  13. private int cost = 0;
  14.  
  15. // 定义一个构造函数,把所有老板需要看到的信息存储起来
  16. public Project(String name, int num, int cost) {
  17. // 赋值到类的成员变量中
  18. this.name = name;
  19. this.num = num;
  20. this.cost = cost;
  21. }
  22.  
  23. // 得到项目的信息
  24. public String getProjectInfo() {
  25. String info = "";
  26. // 获得项目的名称
  27. info = info + "项目名称是:" + this.name;
  28. // 获得项目人数
  29. info = info + "\t项目人数: " + this.num;
  30. // 项目费用
  31. info = info + "\t 项目费用:" + this.cost;
  32. return info;
  33. }
  34. }

实现类也是比较简单的,通过构造函数传递过来要显示的数据,然后放到getProjectInfo 中显示,这太easy 了!,然后我们老大要看看结果了:

  1. package cn.mjorcen.iterator_pattern;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. /**
  6. * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
  7. * all. 老板来看项目信息了
  8. */
  9. public class Boss {
  10. public static void main(String[] args) {
  11. // 定义一个List,存放所有的项目对象
  12. ArrayList<IProject> projectList = new ArrayList<IProject>();
  13. // 增加星球大战项目
  14. projectList.add(new Project("星球大战项目", 10, 100000));
  15. // 增加扭转时空项目
  16. projectList.add(new Project("扭转时空项目", 100, 10000000));
  17. // 增加超人改造项目
  18. projectList.add(new Project("超人改造项目", 10000, 1000000000));
  19. // 这边100个项目
  20. for (int i = 4; i < 104; i++) {
  21. projectList.add(new Project("第" + i + "个项目", i * 5, i * 1000000));
  22. }
  23. // 遍历一下ArrayList,把所有的数据都取出
  24. for (IProject project : projectList) {
  25. System.out.println(project.getProjectInfo());
  26. }
  27. }
  28. }

然后看一下我们的运行结果:

  1. 项目名称是:星球大战项目项目人数: 10 项目费用:100000
  2. 项目名称是:扭转时空项目项目人数: 100 项目费用:10000000
  3. 项目名称是:超人改造项目项目人数: 10000 项目费用:1000000000
  4. 项目名称是:第4个项目项目人数: 20 项目费用:4000000
  5. 项目名称是:第5个项目项目人数: 25 项目费用:5000000
  6. .
  7. .
  8. .

老大一看,非常Happy,这么快就出结果了,大大的把我夸奖了一番,然后就去埋头去研究那堆枯燥的报
表了,然后我回到座位上,又看了一遍程序(心里很乐,就又想看看自己的成果),想想了,应该还有另外一种
实现方式,因为是遍历嘛,让我想到的就是迭代器模式,我先把类图画出来:

看着是不是复杂了很多?是的,是有点复杂了,这个我等会说明原因,我们看代码实现,先IProject 接口:

  1. package cn.mjorcen.iterator_pattern;
  2.  
  3. /**
  4. * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
  5. * all. 定义一个接口,所有的项目都是一个接口
  6. */
  7. public interface IProject {
  8. // 增加项目
  9. public void add(String name, int num, int cost);
  10.  
  11. // 从老板这里看到的就是项目信息
  12. public String getProjectInfo();
  13.  
  14. // 获得一个可以被遍历的对象
  15. public IProjectIterator iterator();
  16. }

这里多了两个方法,一个是add 方法,这个方法是增加项目,也就是说产生了一个对象后,直接使用add
方法增加项目信息。我们再来看实现类:

  1. package cn.mjorcen.iterator_pattern;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. /**
  6. * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
  7. * all. 所有项目的信息类
  8. */
  9. @SuppressWarnings("all")
  10. public class Project implements IProject {
  11. // 定义一个项目列表,说有的项目都放在这里
  12. private ArrayList<IProject> projectList = new ArrayList<IProject>();
  13. // 项目名称
  14. private String name = "";
  15. // 项目成员数量
  16. private int num = 0;
  17. // 项目费用
  18. private int cost = 0;
  19.  
  20. public Project() {
  21. }
  22.  
  23. // 定义一个构造函数,把所有老板需要看到的信息存储起来
  24. private Project(String name, int num, int cost) {
  25. // 赋值到类的成员变量中
  26. this.name = name;
  27. this.num = num;
  28. this.cost = cost;
  29. }
  30.  
  31. // 增加项目
  32. public void add(String name, int num, int cost) {
  33. this.projectList.add(new Project(name, num, cost));
  34. }
  35.  
  36. // 得到项目的信息
  37. public String getProjectInfo() {
  38. String info = "";
  39. // 获得项目的名称
  40. info = info + "项目名称是:" + this.name;
  41. // 获得项目人数
  42. info = info + "\t项目人数: " + this.num;
  43. // 项目费用
  44. info = info + "\t 项目费用:" + this.cost;
  45. return info;
  46. }
  47.  
  48. // 产生一个遍历对象
  49. public IProjectIterator iterator() {
  50. return new ProjectIterator(this.projectList);
  51. }
  52. }

项目信息类已经产生,我们再来看看我们的迭代器是如何实现的,先看接口:

  1. package cn.mjorcen.iterator_pattern;
  2.  
  3. import java.util.Iterator;
  4.  
  5. /**
  6. * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
  7. * all. 定义个Iterator接口
  8. */
  9. @SuppressWarnings("all")
  10. public interface IProjectIterator extends Iterator {
  11. }

大家可能很奇怪,你定义的这个接口方法、变量都没有,有什么意义呢?有意义,所有的Java 书上都一直
说是面向接口编程,你的接口是对一个事物的描述,也就是说我通过接口就知道这个事物有哪些方法,哪些属性,
我们这里的IProjectIterator 是要建立一个指向Project 类的迭代器,目前暂时定义的就是一个通用的迭
代器,可能以后会增加IProjectIterator 的一些属性或者方法。当然了,你也可以在实现类上实现两个接口,
一个是Iterator,一个是IProjectIterator(这时候,这个接口就不用继承Iterator),杀猪杀尾巴,
各有各的杀发。我的习惯是:如果我要实现一个容器或者其他API 提供接口时,我一般都自己先写一个接口继
承,然后再继承自己写的接口,保证自己的实现类只用实现自己写的接口(接口传递,当然也要实现顶层的接口),
程序阅读也清晰一些。我们继续看迭代器的实现类:

  1. package cn.mjorcen.iterator_pattern;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. /**
  6. * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
  7. * all. 定义一个迭代器
  8. */
  9. public class ProjectIterator implements IProjectIterator {
  10. // 所有的项目都放在这里ArrayList中
  11. private ArrayList<IProject> projectList = new ArrayList<IProject>();
  12. private int currentItem = 0;
  13.  
  14. // 构造函数传入projectList
  15. public ProjectIterator(ArrayList<IProject> projectList) {
  16. this.projectList = projectList;
  17. }
  18.  
  19. // 判断是否还有元素,必须实现
  20. public boolean hasNext() {
  21. // 定义一个返回值
  22. boolean b = true;
  23. if (this.currentItem >= projectList.size()
  24. || this.projectList.get(this.currentItem) == null) {
  25. b = false;
  26. }
  27. return b;
  28. }
  29.  
  30. // 取得下一个值
  31. public IProject next() {
  32. return (IProject) this.projectList.get(this.currentItem++);
  33. }
  34.  
  35. // 删除一个对象
  36. public void remove() {
  37. // 暂时没有使用到
  38. }
  39. }

都写完毕了,然后看看我们的Boss 类有多少改动:

  1. package cn.mjorcen.iterator_pattern;
  2.  
  3. /**
  4. * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you
  5. * all. 老板来看项目信息了
  6. */
  7. public class Boss {
  8. public static void main(String[] args) {
  9. // 定义一个List,存放所有的项目对象
  10. IProject project = new Project();
  11. // 增加星球大战项目
  12. project.add("星球大战项目ddddd", 10, 100000);
  13. // 增加扭转时空项目
  14. project.add("扭转时空项目", 100, 10000000);
  15. // 增加超人改造项目
  16. project.add("超人改造项目", 10000, 1000000000);
  17. // 这边100个项目
  18. for (int i = 4; i < 104; i++) {
  19. project.add("第" + i + "个项目", i * 5, i * 1000000);
  20. }
  21. // 遍历一下ArrayList,把所有的数据都取出
  22. IProjectIterator projectIterator = project.iterator();
  23. while (projectIterator.hasNext()) {
  24. IProject p = (IProject) projectIterator.next();
  25. System.out.println(p.getProjectInfo());
  26. }
  27. }
  28. }

运行结果如下:

  1. 项目名称是:星球大战项目项目人数: 10 项目费用:100000
  2. 项目名称是:扭转时空项目项目人数: 100 项目费用:10000000
  3. 项目名称是:超人改造项目项目人数: 10000 项目费用:1000000000
  4. 项目名称是:第4个项目项目人数: 20 项目费用:4000000
  5. 项目名称是:第5个项目项目人数: 25 项目费用:5000000
  6. .
  7. .
  8. .

上面的程序增加了复杂性,但是从面向对象的开发上来看,project.add()增加一个项目是不是更友好一
些?
上面的例子就使用了迭代器模式,我们来看看迭代器的通用类图:

  类图是很简单,但是你看用起来就很麻烦,就比如上面例子的两个实现方法,你觉的那个简单?当然是第一
个了!23 个设计模式是为了简化我们代码和设计的复杂度、耦合程度,为什么我们用了这个迭代器模式程序会
复杂了一些呢?这是为什么?因为从JDK 1.2 版本开始增加java.util.Iterator 这个接口,并逐步把
Iterator 应用到各个聚集类(Collection)中,我们来看JDK 1.5 的API 帮助文件,你会看到有一个叫
java.util.Iterable 的接口,看看有多少个接口继承了它:

java.util.Iterable 接口只有一个方法:iterator(),也就说通过iterator()这个方法去遍历聚
集类中的所有方法或属性,基本上现在所有的高级的语言都有Iterator 这个接口或者实现,Java 已经把迭代
器给我们准备了,我们再去写迭代器,是不是“六指儿抓痒,多一道子”?所以呀,这个迭代器模式也有点没落
了,基本上很少有项目再独立写迭代器了,直接使用List 或者Map 就可以完整的解决问题。

第 14 章 迭代器模式【Iterator Pattern】的更多相关文章

  1. 设计模式(十):从电影院中认识"迭代器模式"(Iterator Pattern)

    上篇博客我们从醋溜土豆丝与清炒苦瓜中认识了“模板方法模式”,那么在今天这篇博客中我们要从电影院中来认识"迭代器模式"(Iterator Pattern).“迭代器模式”顾名思义就是 ...

  2. 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)

    原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...

  3. 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)

    设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...

  4. 二十四种设计模式:迭代器模式(Iterator Pattern)

    迭代器模式(Iterator Pattern) 介绍提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 示例有一个Message实体类,某聚合对象内的各个元素均为该实体对象,现 ...

  5. 设计模式 - 迭代器模式(iterator pattern) 具体解释

    迭代器模式(iterator pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 迭代器模式(iterator pattern) : 提供一 ...

  6. 设计模式系列之迭代器模式(Iterator Pattern)——遍历聚合对象中的元素

    模式概述 模式定义 模式结构图 模式伪代码 模式改进 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修 ...

  7. C#设计模式——迭代器模式(Iterator Pattern)

    一.概述在软件开发过程中,我们可能会希望在不暴露一个集合对象内部结构的同时,可以让外部代码透明地访问其中包含的元素.迭代器模式可以解决这一问题.二.迭代器模式迭代器模式提供一种方法顺序访问一个集合对象 ...

  8. 迭代器模式(Iterator Pattern)

    迭代器模式定义:Iterator Pattern提供一种方法顺序访问一个聚合元素中的各个元素,而又不暴漏内部方法 酒吧提供beer和wine: public class Bar { private L ...

  9. 16.迭代器模式(Iterator Pattern)

    using System; namespace ConsoleApplication9 { class Program { /// <summary> /// 迭代器模式提供了一种方法顺序 ...

随机推荐

  1. 给未来的你——李开复2011级大学新生演讲

    2011年09月26日08:30 来源:<中国青年报> <中国青年报>的读者朋友们: 你们肩负着中华的未来,你们身上正涌动着创新的血脉! 无论你在哪所学校,哪个城市,你都是与众 ...

  2. 读写应用程序数据-SQLite3

    SQLite3是嵌入到ios中的关系型数据库.对存储大规模的数据非常实用,使得不必将每个对象加到内存中. 支持NULL.INTEGER.REAL(浮点数字).TEXT(字符串和文本).BLOB(二进制 ...

  3. 검색엔진의 크롤링과 인덱싱의 차이 (robots.txt 파일과 meta robots 태그의 차이점)

    검색엔진의 크롤링과 인덱싱의 차이크롤링 제어는 robots.txt인덱싱 제어는 < meta name="robots" content="noindex& ...

  4. PHP中的ob_start() 的使用

    1.在PHP编程中, 我们经常会遇到一些直接产生输出的函数, 如passthru(),readfile(), var_dump() 等. 但有时我们想把这些函数的输出导入到文件中,或者先经过处理再输出 ...

  5. Ajax编程技术

    AJAX:”Asynchronous JavaScript and XML” 中文意思:异步JavaScript和XML. 指一种创建交互式网页应用的网页开发技术. 不是指一种单一的技术,而是有机地利 ...

  6. Android开发5大布局方式详解

    Android中常用的5大布局方式有以下几种: 线性布局(LinearLayout):按照垂直或者水平方向布局的组件. 帧布局(FrameLayout):组件从屏幕左上方布局组件. 表格布局(Tabl ...

  7. JavaWeb_Day10_学习笔记1_response(3、4、5、6、7、8、9)发送状态码、响应、重定向、定时刷新、禁用浏览器缓存、响应字节数据、快捷重定向方法、完成防盗链

    今天学习重点: 1.response和request响应和应答分别学习: 请求响应流程图 response 1        response概述 response是Servlet.service方法 ...

  8. ios专题 - 图片(UIImage)获取方法

    说到图片获取的方法,就得看API文档. UIImage生成实例的方法有: 1)imageNamed 从指定文件返回对象. 这个方法有个比较特殊的地方:该方法首先从系统缓存中寻找该图片,如果有,则从缓存 ...

  9. 09.13日记(2014年9月13日00:18:26)英语,bootstrap,阮一峰,

    我们这里只推荐一本语法书:台湾的旋元佑老师写的<文法俱乐部>(简体版名为<语法俱乐部>).这本书因为出版社倒闭而绝版,淘宝可以买到影印的版本. (1)学英语:奶爸的英语教室 资 ...

  10. Poj 3061 Subsequence(二分+前缀和)

    Subsequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12333 Accepted: 5178 Descript ...