迭代器模式【Iterator Pattern】
2017-05-27 16:24
477 查看
周五下午,我正在看技术网站,第六感官发觉有人在身后,扭头一看,我 C,老大站在背后,赶忙站起来,“王经理,你找我?” 我说。“哦,在看技术呀。有个事情找你谈一下,你到我办公室来一下。” 老大说。到老大办公室,“是这样,刚刚我在看季报,我们每个项目的支出费用都很高,项目情况复杂,人员情况也不简单,我看着也有点糊涂,你看,这是我们现在还在开发或者维护的 103 个项目,你能不能先把这些项目信息重新打印一份给我,咱们好查查到底有什么问题。”老大说。“这个好办,我马上去办”我爽快的答复道。
很快我设计了一个类图,并开始实施:
package com.cbf4life;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 定义一个接口,所有的项目都是一个接口
*/
public interface IProject {
//从老板这里看到的就是项目信息
public String getProjectInfo();
} 定义了一个接口,面向接口编程嘛,当然要定义接口了,然后看看实现类:
4000
过来要显示的数据,然后放到 getProjectInfo 中显示,这太easy 了!,然后我们老大要看看结果了:
看着是不是复杂了很多?是的,是有点复杂了,这个我等会说明原因,我们看代码实现,先 IProject 接口:
package com.cbf4life.pattern;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 定义一个接口,所有的项目都是一个接口
*/
public interface IProject {
//增加项目
public void add(String name,int num,int cost);
//从老板这里看到的就是项目信息
public String getProjectInfo();
//获得一个可以被遍历的对象
public IProjectIterator iterator();
} 这里多了两个方法,一个是 add 方法,这个方法是增加项目,也就是说产生了一个对象后,直接使用 add方法增加项目信息。我们再来看实现类:
IProjectIterator(这时候,这个接口就不用继承 Iterator),杀猪杀尾巴,各有各的杀发。我的习惯是:如果我要实现一个容器或者其他 API 提供接口时,我一般都自己先写一个接口继承,然后再继承自己写的接口,保证自己的实现类只用实现自己写的接口(接口传递,当然也要实现顶层的接口),程序阅读也清晰一些。我们继续看迭代器的实现类:
上面的例子就使用了迭代器模式,我们来看看迭代器的通用类图:
类图是很简单,但是你看用起来就很麻烦,就比如上面例子的两个实现方法,你觉的那个简单?当然是第一个了!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 就可以完整的解决问题。
很快我设计了一个类图,并开始实施:
package com.cbf4life;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 定义一个接口,所有的项目都是一个接口
*/
public interface IProject {
//从老板这里看到的就是项目信息
public String getProjectInfo();
} 定义了一个接口,面向接口编程嘛,当然要定义接口了,然后看看实现类:
package com.cbf4life; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 所有项目的信息类 */ public class Project implements IProject { //项目名称 private String name = ""; //项目成员数量 private int num = 0; //项目费用 private int cost = 0; //定义一个构造函数,把所有老板需要看到的信息存储起来 public Project(String name,int num,int cost){ //赋值到类的成员变量中 this.name = name; this.num = num; this.cost=cost; } //得到项目的信息 public String getProjectInfo() { String info = ""; //获得项目的名称 info = info+ "项目名称是:" + this.name; //获得项目人数 info = info + "\t项目人数: "+ this.num; //项目费用 info = info+ "\t 项目费用:"+ this.cost; return info; } }实现类也是比较简单的,通过构造函数传递
4000
过来要显示的数据,然后放到 getProjectInfo 中显示,这太easy 了!,然后我们老大要看看结果了:
package com.cbf4life; import java.util.ArrayList; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 老板来看项目信息了 */ public class Boss { public static void main(String[] args) { //定义一个List,存放所有的项目对象 ArrayList<IProject> projectList = new ArrayList<IProject>(); //增加星球大战项目 projectList.add(new Project("星球大战项目",10,100000)); //增加扭转时空项目 projectList.add(new Project("扭转时空项目",100,10000000)); //增加超人改造项目 projectList.add(new Project("超人改造项目",10000,1000000000)); //这边100个项目 for(int i=4;i<104;i++){ projectList.add(new Project("第"+i+"个项目",i*5,i*1000000)); } //遍历一下ArrayList,把所有的数据都取出 for(IProject project:projectList){ System.out.println(project.getProjectInfo()); } } }然后看一下我们的运行结果:
项目名称是:星球大战项目 项目人数: 10 项目费用:100000 项目名称是:扭转时空项目 项目人数: 100 项目费用:10000000 项目名称是:超人改造项目 项目人数: 10000 项目费用:1000000000 项目名称是:第4个项目 项目人数: 20 项目费用:4000000 项目名称是:第5个项目 项目人数: 25 项目费用:5000000 . . .老大一看,非常 Happy,这么快就出结果了,大大的把我夸奖了一番,然后就去埋头去研究那堆枯燥的报表了,然后我回到座位上,又看了一遍程序(心里很乐,就又想看看自己的成果),想想了,应该还有另外一种实现方式,因为是遍历嘛,让我想到的就是迭代器模式,我先把类图画出来:
看着是不是复杂了很多?是的,是有点复杂了,这个我等会说明原因,我们看代码实现,先 IProject 接口:
package com.cbf4life.pattern;
/**
* @author cbf4Life cbf4life@126.com
* I'm glad to share my knowledge with you all.
* 定义一个接口,所有的项目都是一个接口
*/
public interface IProject {
//增加项目
public void add(String name,int num,int cost);
//从老板这里看到的就是项目信息
public String getProjectInfo();
//获得一个可以被遍历的对象
public IProjectIterator iterator();
} 这里多了两个方法,一个是 add 方法,这个方法是增加项目,也就是说产生了一个对象后,直接使用 add方法增加项目信息。我们再来看实现类:
package com.cbf4life.pattern; import java.util.ArrayList; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 所有项目的信息类 */ @SuppressWarnings("all") public class Project implements IProject { //定义一个项目列表,说有的项目都放在这里 private ArrayList<IProject> projectList = new ArrayList<IProject>(); //项目名称 private String name = ""; //项目成员数量 private int num = 0; //项目费用 private int cost = 0; public Project(){ } //定义一个构造函数,把所有老板需要看到的信息存储起来 private Project(String name,int num,int cost){ //赋值到类的成员变量中 this.name = name; this.num = num; this.cost=cost; } //增加项目 public void add(String name,int num,int cost){ this.projectList.add(new Project(name,num,cost)); } //得到项目的信息 public String getProjectInfo() { String info = ""; //获得项目的名称 info = info+ "项目名称是:" + this.name; //获得项目人数 info = info + "\t项目人数: "+ this.num; //项目费用 info = info+ "\t 项目费用:"+ this.cost; return info; } //产生一个遍历对象 public IProjectIterator iterator(){ return new ProjectIterator(this.projectList); } }项目信息类已经产生,我们再来看看我们的迭代器是如何实现的,先看接口:
package com.cbf4life.pattern; import java.util.Iterator; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 定义个Iterator接口 */ @SuppressWarnings("all") public interface IProjectIterator extends Iterator { }大家可能很奇怪,你定义的这个接口方法、变量都没有,有什么意义呢?有意义,所有的 Java 书上都一直说是面向接口编程,你的接口是对一个事物的描述,也就是说我通过接口就知道这个事物有哪些方法,哪些属性,我们这里的 IProjectIterator 是要建立一个指向 Project 类的迭代器,目前暂时定义的就是一个通用的迭代器,可能以后会增加 IProjectIterator 的一些属性或者方法。当然了,你也可以在实现类上实现两个接口,一个是 Iterator,一个是
IProjectIterator(这时候,这个接口就不用继承 Iterator),杀猪杀尾巴,各有各的杀发。我的习惯是:如果我要实现一个容器或者其他 API 提供接口时,我一般都自己先写一个接口继承,然后再继承自己写的接口,保证自己的实现类只用实现自己写的接口(接口传递,当然也要实现顶层的接口),程序阅读也清晰一些。我们继续看迭代器的实现类:
package com.cbf4life.pattern; import java.util.ArrayList; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 定义一个迭代器 */ public class ProjectIterator implements IProjectIterator { //所有的项目都放在这里ArrayList中 private ArrayList<IProject> projectList = new ArrayList<IProject>(); private int currentItem = 0; //构造函数传入projectList public ProjectIterator(ArrayList<IProject> projectList){ this.projectList = projectList; } //判断是否还有元素,必须实现 public boolean hasNext() { //定义一个返回值 boolean b = true; if(this.currentItem>=projectList.size() || this.projectList.get(this.currentItem) == null){ b =false; } return b; } //取得下一个值 public IProject next() { return (IProject)this.projectList.get(this.currentItem++); } //删除一个对象 public void remove() { //暂时没有使用到 } }都写完毕了,然后看看我们的 Boss 类有多少改动:
package com.cbf4life.pattern; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 老板来看项目信息了 */ public class Boss { public static void main(String[] args) { //定义一个List,存放所有的项目对象 IProject project = new Project(); //增加星球大战项目 project.add("星球大战项目ddddd",10,100000); //增加扭转时空项目 project.add("扭转时空项目",100,10000000); //增加超人改造项目 project.add("超人改造项目",10000,1000000000); //这边100个项目 for(int i=4;i<104;i++){ project.add("第"+i+"个项目",i*5,i*1000000); } //遍历一下ArrayList,把所有的数据都取出 IProjectIterator projectIterator = project.iterator(); while(projectIterator.hasNext()){ IProject p = (IProject)projectIterator.next(); System.out.println(p.getProjectInfo()); } } }运行结果如下:
项目名称是:星球大战项目 项目人数: 10 项目费用:100000 项目名称是:扭转时空项目 项目人数: 100 项目费用:10000000 项目名称是:超人改造项目 项目人数: 10000 项目费用:1000000000 项目名称是:第4个项目 项目人数: 20 项目费用:4000000 项目名称是:第5个项目 项目人数: 25 项目费用:5000000 . . .上面的程序增加了复杂性,但是从面向对象的开发上来看,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 就可以完整的解决问题。
相关文章推荐
- 设计模式:迭代器模式(Iterator Pattern)
- 设计模式之九:迭代器模式(Iterator Pattern)
- 软件设计模式——迭代器模式(Iterator Pattern)
- 迭代器模式(Iterator Pattern)
- 【17】迭代器模式(Iterator Pattern)
- Net设计模式实例之迭代器模式(Iterator Pattern)
- java设计模式——迭代器模式(Iterator Pattern)
- Iterator Pattern 迭代器模式
- Php设计模式之【迭代器模式Iterator Pattern】
- Java设计模式--迭代器模式【Iterator Pattern】
- Java Iterator Pattern(迭代器模式)
- 23种设计模式(15)_行为型_迭代器模式(Iterator Pattern)
- 设计模式(16)——迭代器模式(Iterator Pattern)
- 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)
- 迭代器模式(Iterator Pattern)
- 迭代器模式(Iterator pattern)
- 迭代器模式(Iterator Pattern)
- Net设计模式实例之迭代器模式(Iterator Pattern)(2) 推荐
- 二十四种设计模式:迭代器模式(Iterator Pattern)
- 十九.行为型设计模式——Iterator Pattern(迭代器模式)