周五下午,我正在看技术网站,第六感官发觉有人在身后,扭头一看,我 C,老大站在背后,赶忙站起来,“王经理,你找我?” 我说。

  “哦,在看技术呀。有个事情找你谈一下,你到我办公室来一下。” 老大说。

  到老大办公室,“是这样,刚刚我在看季报,我们每个项目的支出费用都很高,项目情况复杂,人员情况也不简单,我看着也有点糊涂,你看,这是我们现在还在开发或者维护的 103 个项目,你能不能先把这些项目信息重新打印一份给我,咱们好查查到底有什么问题。”老大说。

  “这个好办,我马上去办”我爽快的答复道。很快我设计了一个类图,并开始实施:

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

  1. package com.pattern.iterator;
  2.  
  3. /**
  4. * 定义一个接口,所有的项目都是一个接口
  5. * @author http://www.cnblogs.com/initial-road/
  6. *
  7. */
  8. public interface IProject {
  9.  
  10. // 从老板这里看到的就是项目信息
  11. public String getProjectInfo();
  12.  
  13. }
  14.  
  15. // 定义了一个接口,面向接口编程嘛,当然要定义接口了,然后看看实现类:
  16.  
  17. package com.pattern.iterator;
  18.  
  19. import java.util.ArrayList;
  20.  
  21. /**
  22. * 所有的项目信息类
  23. * @author http://www.cnblogs.com/initial-road/
  24. *
  25. */
  26. public class Project implements IProject {
  27. // 项目名称
  28. private String name = "";
  29.  
  30. // 项目成员数量
  31. private int num = 0;
  32.  
  33. // 项目费用
  34. private int cost = 0;
  35.  
  36. public Project(){
  37.  
  38. }
  39.  
  40. // 定义一个构造函数,把所有老板需要看到的信息存储起来
  41. public Project(String name, int num, int cost){
  42. // 赋值到类的成员变量中
  43. this.name = name;
  44. this.num = num;
  45. this.cost = cost;
  46. }
  47.  
  48. // 得到项目的信息
  49. public String getProjectInfo() {
  50. String info = "";
  51.  
  52. // 获得项目的名称
  53. info = info + "项目名称是:" + this.name;
  54. // 获得项目人数
  55. info = info + "\t 项目人数:" + this.num;
  56. // 项目费用
  57. info = info + "\t 项目费用:" + this.cost;
  58.  
  59. return info;
  60. }
  61.  
  62. }

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

  1. package com.pattern.iterator;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. /**
  6. * 老板来看项目信息了
  7. * @author http://www.cnblogs.com/initial-road/
  8. *
  9. */
  10. public class Boss {
  11.  
  12. public static void main(String[] args) {
  13. // 定义一个List,存放所有的项目对象
  14. ArrayList<IProject> projectList = new ArrayList<IProject>();
  15.  
  16. // 增加星球大战项目
  17. projectList.add(new Project("星球大战项目", 10, 100000));
  18.  
  19. // 增加扭转时空项目
  20. projectList.add(new Project("扭转时空项目", 100, 100000));
  21.  
  22. // 增加超人改造项目
  23. projectList.add(new Project("超人改造项目", 10000, 1000000000));
  24.  
  25. // 这边100个项目
  26. for(int i=4;i<104;i++){
  27. projectList.add(new Project("第" + i + "个项目", 1*5, 1*100000));
  28. }
  29.  
  30. // 遍历一下ArrayList,把所有的数据都取出
  31. for(IProject project : projectList){
  32. System.out.println(project.getProjectInfo());
  33. }
  34. }
  35.  
  36. }

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

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

  1. package com.pattern.iterator;
  2.  
  3. /**
  4. * 定义一个接口,所有的项目都是一个接口
  5. * @author http://www.cnblogs.com/initial-road/
  6. *
  7. */
  8. public interface IProject {
  9.  
  10. // 增加项目
  11. public void add(String name, int num, int cost);
  12.  
  13. // 从老板这里看到的就是项目信息
  14. public String getProjectInfo();
  15.  
  16. // 获得一个可以被遍历的对象
  17. public IProjectIterator iterator();
  18. }

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

  1. package com.pattern.iterator;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. /**
  6. * 所有的项目信息类
  7. * @author http://www.cnblogs.com/initial-road/
  8. *
  9. */
  10. public class Project implements IProject {
  11. // 定义一项项目列表,所有的项目都放在这里
  12. private ArrayList<IProject> projectList = new ArrayList<IProject>();
  13.  
  14. // 项目名称
  15. private String name = "";
  16.  
  17. // 项目成员数量
  18. private int num = 0;
  19.  
  20. // 项目费用
  21. private int cost = 0;
  22.  
  23. public Project(){
  24.  
  25. }
  26.  
  27. // 定义一个构造函数,把所有老板需要看到的信息存储起来
  28. public Project(String name, int num, int cost){
  29. // 赋值到类的成员变量中
  30. this.name = name;
  31. this.num = num;
  32. this.cost = cost;
  33. }
  34.  
  35. // 得到项目的信息
  36. public String getProjectInfo() {
  37. String info = "";
  38.  
  39. // 获得项目的名称
  40. info = info + "项目名称是:" + this.name;
  41. // 获得项目人数
  42. info = info + "\t 项目人数:" + this.num;
  43. // 项目费用
  44. info = info + "\t 项目费用:" + this.cost;
  45.  
  46. return info;
  47. }
  48.  
  49. @Override
  50. public void add(String name, int num, int cost) {
  51. this.projectList.add(new Project(name, num, cost));
  52. }
  53.  
  54. @Override
  55. public IProjectIterator iterator() {
  56. return new ProjectIterator(this.projectList);
  57. }
  58.  
  59. }
  60.  
  61. // 项目信息类已经产生,我们再来看看我们的迭代器是如何实现的,先看接口:
  62.  
  63. package com.pattern.iterator;
  64.  
  65. import java.util.Iterator;
  66.  
  67. @SuppressWarnings("all")
  68. public interface IProjectIterator extends Iterator {
  69.  
  70. }

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

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

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

  1. package com.pattern.iterator;
  2.  
  3. import java.util.ArrayList;
  4.  
  5. /**
  6. * 老板来看项目信息了
  7. * @author http://www.cnblogs.com/initial-road/
  8. *
  9. */
  10. public class Boss {
  11.  
  12. public static void main(String[] args) {
  13. // 定义一个List,存放所有的项目对象
  14. IProject project = new Project();
  15.  
  16. // 增加星球大战项目
  17. project.add("星球大战项目dddd", 10, 100000);
  18.  
  19. // 增加扭转时空项目
  20. project.add("扭转时空项目", 100, 1000000);
  21.  
  22. // 增加超人改造项目
  23. project.add("超人改造项目", 10000, 100000000);
  24.  
  25. // 这边100个项目
  26. for(int i=4;i<104;i++){
  27. project.add("第" + i + "个项目", i*5, i*1000000);
  28. }
  29.  
  30. // 遍历一下ArrayList,把所有的数据都取出
  31. IProjectIterator projectIterator = project.iterator();
  32. while(projectIterator.hasNext()){
  33. IProject p = (IProject) projectIterator.next();
  34. System.out.println(p.getProjectInfo());
  35. }
  36. }
  37.  
  38. }

  上面的程序增加了复杂性,但是从面向对象的开发上来看, 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 就可以完整的解决问题。

24种设计模式--迭代模式【Iterator Pattern】的更多相关文章

  1. 设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释

    迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(ite ...

  2. 24种设计模式-策略模式(Strategy Pattern)

    一.优点: 1. 策略模式提供了管理相关的算法族的办法.策略类的等级结构定义了一个算法或行为族.恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码. 2. 策略模式提供了可以替换继承关系的 ...

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

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

  4. 24种设计模式--访问者模式【Visitor Pattern】

    今天天气不错,绝对是晴空万里,骄阳似火呀,好,我们今天来讲访问者模式,我们在前面讲了组合模式和迭代器模式,通过组合模式我们能够把一个公司的人员组织机构树搭建起来,给管理带来非常大的便利,通过迭代器模式 ...

  5. 24种设计模式--原型模式【Prototype Pattern】

    今天我们来讲原型模式,这个模式的简单程度是仅次于单例模式和迭代器模式,非常简单,但是要使用好这个模式还有很多注意事项.我们通过一个例子来解释一下什么是原型模式. 现在电子账单越来越流行了,比如你的信用 ...

  6. 24种设计模式--组合模式【Composite Pattern】

    大家在上学的时候应该都学过“数据结构”这门课程吧,还记得其中有一节叫“二叉树”吧,我们上学那会儿这一章节是必考内容,左子树,右子树,什么先序遍历后序遍历什么,重点就是二叉树的的遍历,我还记得当时老师就 ...

  7. 24种设计模式--命令模式【Command Pattern】

    今天讲命令模式,这个模式从名字上看就很简单,命令嘛,老大发命令,小兵执行就是了,确实是这个意思,但是更深化了,用模式来描述真实世界的命令情况.正在看这本书的你,我猜测分为两类:已经工作的和没有工作的, ...

  8. 24种设计模式--建造者模式【Builder Pattern】

    在一个周三,快要下班了,老大突然又拉住我,喜滋滋的告诉我“牛叉公司很满意我们做的模型,又签订了一个合同,把奔驰.宝马的车辆模型都交给我们公司制作了,不过这次又额外增加了一个新需求:汽车的启动.停止.喇 ...

  9. 24种设计模式--门面模式【Facade Pattern】

    大家都写过纸质的信件吧,比如给女朋友写情书什么的,写信的过程大家都还记得吧,先写信的内容,然后写信封,把信放到信封中,封好,投递到信箱中进行邮递,这个过程还是比较简单的,虽然简单,这四个步骤都是要跑的 ...

随机推荐

  1. [SAN4N学习笔记]使用SysTick精准延时

    一.准备工作:      将上一节搭建的LED工程复制一份,命名为"2.systick".这一节主要讲如何使用系统的SysTick节拍定时器来进行精准延时程序. 二.程序编写: S ...

  2. HW4.30

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  3. opencv Installation in Linux and hello world

    http://opencv.org/quickstart.html Installation in Linux These steps have been tested for Ubuntu 10.0 ...

  4. LIS,LDS的另类算法(原)

    自己在做有关俄罗斯套娃的题目时,发现自己写出的一个方法可以解决求最长上升子序列(LIS)和最长下降子序列(LDS)的问题. 俄罗斯套娃:这个问题在前一篇中讲的有,在此处就不多讲了~链接  求最长上升子 ...

  5. 用jQuery实现优酷首页轮播图

    ▓▓▓▓▓▓ 大致介绍 看到了一个轮播图的思路,就想的自己动手实践一下,总体来说用jQuery实现起来简单多了 如果对代码中使用的方法有疑问,可以参考我的jQuery学习之路(持续更新),里面有讲解: ...

  6. 连接数据库超时设置autoReconnect=true

    1,问题现象: com.mysql.jdbc.CommunicationsException: The last packet successfully received from the serve ...

  7. Hibernate—第一个案例

    百度百科上是这样写道的:Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可 ...

  8. ABAP SAPGUI_PROGRESS_INDICATOR 显示数据处理进度

    ABAP处理的数据量较大时,盯着一动不动的选择屏幕是不是很无聊?? LOOP AT I_TAB. DESCRIBE TABLE I_TAB[] LINES L_LIN. L_PERC = SY-TAB ...

  9. CONTROLS: <> TYPE TABLEVIEW USING SCREEN<>.在 ABAP/4 中声明表格 控制

    在 ABAP/4 中声明表格 控制 在屏幕中使 用表格控制 时,必须在 ABAP/4 程序中同时 声明表格控 制结构和表 格控制字段 . 例如: TABLES:   SFLIGHT. CONTROLS ...

  10. inline-block元素之间出现间隙

    一.问题 这里部分的组成是一个input框和一个a按钮,然后a标签为了设置它的width和height我让他display:inline-block(行内元素以块级元素显示内容).神奇的一幕出现了,两 ...