24种设计模式--迭代模式【Iterator Pattern】

  周五下午,我正在看技术网站,第六感官发觉有人在身后,扭头一看,我 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 就可以完整的解决问题。

时间: 01-08

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

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

迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(iterator pattern): http://blog.csdn.net/caroline_wendy/article/details/35254643 Java的标准库(util)中包括迭代器接口(iterator interface), import java.util.Iterator; 继承

设计模式 - 迭代器模式(iterator pattern) 详解

迭代器模式(iterator pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy 迭代器模式(iterator pattern) : 提供一种方法顺序访问一个聚合对象中的各个元素, 而又不暴露其内部的表示; 建立迭代器接口(iterator interface), 包含hasNext()方法和next()方法; 不同聚合对象的具体的迭代器(concrete iterator), 继承(implements)迭代器接口(iterator in

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

迭代器模式(iterator pattern) Java 迭代器(Iterator) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考迭代器模式(iterator pattern): http://blog.csdn.net/caroline_wendy/article/details/35254643 Java的标准库(util)中包含迭代器接口(iterator interface), import java.util.Iterator; 继承(

设计模式 - 迭代器模式(iterator pattern) 扩展 详解

迭代器模式(iterator pattern) 扩展 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考迭代器模式-Java迭代器: http://blog.csdn.net/caroline_wendy/article/details/35268931 扩展迭代器模式, 添加一个Hashtable存储的类. 具体方法: 1. Hashtable的类, 包含创建value()的迭代器(iterator). /** * @time 2014年6月27日

24种设计模式--门面模式【Facede Pattern】

大家都写过纸质的信件吧,比如给女朋友写情书什么的,写信的过程大家都还记得吧,先写信的内容,然后写信封,把信放到信封中,封好,投递到信箱中进行邮递,这个过程还是比较简单的,虽然简单,这四个步骤都是要跑的呀,信多了还是麻烦,比如到了情人节,为了大海捞针,给十个女孩子发情书,都要这样跑一遍,你不要累死,更别说你要发个广告信啥的,一下子发 1 千万封邮件,那不就完蛋了?那怎么办呢?还好,现在邮局开发了一个新业务,你只要把信件的必要信息告诉我,我给你发,我来做这四个过程,你就不要管了,只要把信件交给我就成

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

今天天气不错,绝对是晴空万里,骄阳似火呀,好,我们今天来讲访问者模式,我们在前面讲了组合模式和迭代器模式,通过组合模式我们能够把一个公司的人员组织机构树搭建起来,给管理带来非常大的便利,通过迭代器模式我们可以把每一个员工都遍历一遍,看看是不是有“人去世了还在领退休金”, “拿高工资而不干活的尸位素餐”等情况,那我们今天的要讲访问者模式是做什么用的呢? 我们公司有七百多技术人员,分布在全国各地,组织架构你在组合模式中也看到了,很常见的家长领导型模式,每个技术人员的岗位都是固定的,你在组织机构的那棵

24种设计模式--桥梁模式【Bridge Pattern】

今天我要说说我自己,梦想中的我自己,我身价过亿,有两个大公司,一个是房地产公司,一个是服装制造业,这两个公司都很赚钱,天天帮我在累加财富,其实是什么公司我倒是不关心,我关心的是是不是在赚钱,赚了多少,我先用类图表示一下我这两个公司: 类图很简单,声明了一个 Corp 抽象类,定义一个公司的抽象模型,公司首先要是赚钱的,不赚钱谁开公司,做义务或善举那也是有背后利益支撑的,我还是赞这句话“天下熙熙,皆为利来:天下壤壤,皆为利往”,那我们先看 Corp 类的源代码: 1 package com.pat

24种设计模式--策略模式【Strategy Pattern】

刘备要到江东娶老婆了,走之前诸葛亮给赵云(伴郎)三个锦囊妙计,说是按天机拆开解决棘手问题,嘿,还别说,真是解决了大问题,搞到最后是周瑜赔了夫人有折兵呀,那咱们先看看这个场景是什么样子的. 先说这个场景中的要素:三个妙计,一个锦囊,一个赵云,妙计是小亮同志给的,妙计是放置在锦囊里,俗称就是锦囊妙计嘛,那赵云就是一个干活的人,从锦囊中取出妙计,执行,然后获胜,用Java程序怎么表现呢? 我们先看类图: 三个妙计是同一类型的东东,那咱就写个接口: 1 package com.iadmob.strate

24种设计模式--单例模式【Singleton Pattern】

这个模式是很有意思,而且比较简单,但是我还是要说因为它使用的是如此广泛,如此的有人缘,单例就是单一.独苗的意思,那什么是独一份呢?你的思维是 独一份,除此之外还有什么不能山寨的呢?我们举个比较难复制的对象:皇帝 中国的历史上很少出现两个皇帝并存的时期,是有,但不多,那我们就认为皇帝是个单例模式,在这个场景中,有皇帝,有大臣,大臣是天天要上朝参见皇帝的,今天参拜的皇帝应用和昨天.前天的一样(过渡期的不考虑),大臣磕完头,抬头一看,嗨,还是昨天那个皇帝,单例模式,绝对的单例模式. 先看类图: 然后我

23种设计模式--工厂模式-Factory Pattern

一.工厂模式的介绍       工厂模式让我们相到的就是工厂,那么生活中的工厂是生产产品的,在代码中的工厂是生产实例的,在直白一点就是生产实例的类,代码中我们常用new关键字,那么这个new出来的实例就就依赖与这个类,2者之间的耦合度就高,此时我们就可以使用面向对象的去解决这个问题,将变化点封装起来,这就是我们将要首先引入的简单工厂模式:先来说一个场景,比如我们吃水果这个例子吧,我们有时候想吃苹果,有时候想吃橘子,但是每次都需要去买这些水果,后来有个水果店,又卖橘子,又卖苹果,这个水果店就当于简