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

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

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

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

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

 package com.pattern.iterator;

 /**
* 定义一个接口,所有的项目都是一个接口
* @author http://www.cnblogs.com/initial-road/
*
*/
public interface IProject { // 从老板这里看到的就是项目信息
public String getProjectInfo(); } // 定义了一个接口,面向接口编程嘛,当然要定义接口了,然后看看实现类: package com.pattern.iterator; import java.util.ArrayList; /**
* 所有的项目信息类
* @author http://www.cnblogs.com/initial-road/
*
*/
public class Project implements IProject {
// 项目名称
private String name = ""; // 项目成员数量
private int num = 0; // 项目费用
private int cost = 0; public Project(){ } // 定义一个构造函数,把所有老板需要看到的信息存储起来
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;
} }

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

 package com.pattern.iterator;

 import java.util.ArrayList;

 /**
* 老板来看项目信息了
* @author http://www.cnblogs.com/initial-road/
*
*/
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, 100000)); // 增加超人改造项目
projectList.add(new Project("超人改造项目", 10000, 1000000000)); // 这边100个项目
for(int i=4;i<104;i++){
projectList.add(new Project("第" + i + "个项目", 1*5, 1*100000));
} // 遍历一下ArrayList,把所有的数据都取出
for(IProject project : projectList){
System.out.println(project.getProjectInfo());
}
} }

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

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

 package com.pattern.iterator;

 /**
* 定义一个接口,所有的项目都是一个接口
* @author http://www.cnblogs.com/initial-road/
*
*/
public interface IProject { // 增加项目
public void add(String name, int num, int cost); // 从老板这里看到的就是项目信息
public String getProjectInfo(); // 获得一个可以被遍历的对象
public IProjectIterator iterator();
}

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

 package com.pattern.iterator;

 import java.util.ArrayList;

 /**
* 所有的项目信息类
* @author http://www.cnblogs.com/initial-road/
*
*/
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(){ } // 定义一个构造函数,把所有老板需要看到的信息存储起来
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;
} @Override
public void add(String name, int num, int cost) {
this.projectList.add(new Project(name, num, cost));
} @Override
public IProjectIterator iterator() {
return new ProjectIterator(this.projectList);
} } // 项目信息类已经产生,我们再来看看我们的迭代器是如何实现的,先看接口: package com.pattern.iterator; import java.util.Iterator; @SuppressWarnings("all")
public interface IProjectIterator extends Iterator { }

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

 package com.pattern.iterator;

 import java.util.ArrayList;

 /**
* 定义一个迭代器
* @author http://www.cnblogs.com/initial-road/
*
*/
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 >= this.projectList.size()
|| this.projectList.get(this.currentItem)==null){
b = false;
}
return b;
} // 获取下一个值
public Object next() {
return (IProject) this.projectList.get(this.currentItem++);
} // 删除一个对象
public void remove() {
// 暂时没有使用到
} }

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

 package com.pattern.iterator;

 import java.util.ArrayList;

 /**
* 老板来看项目信息了
* @author http://www.cnblogs.com/initial-road/
*
*/
public class Boss { public static void main(String[] args) {
// 定义一个List,存放所有的项目对象
IProject project = new Project(); // 增加星球大战项目
project.add("星球大战项目dddd", 10, 100000); // 增加扭转时空项目
project.add("扭转时空项目", 100, 1000000); // 增加超人改造项目
project.add("超人改造项目", 10000, 100000000); // 这边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());
}
} }

  上面的程序增加了复杂性,但是从面向对象的开发上来看, 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. Yslow 之 高性能网站建设指南(High.Performance.Web.Sites)

    一个朋友做了2年前端重构,不知道 YSLOW.我推荐给他的时候,他惊呼这工具很强大. YSLOW 只是 Yahoo 前端发布的一个评测网站前端质量的插件.它的原理是基于 Yahoo 前端工程师提出来的 ...

  2. InetAddress Example program in Java

    The InetAddress class has no visible constructors. To create an InetAddress object, you have to use ...

  3. 关于 vim每次w时都提示 “E509: 无法创建备份文件 (请加 ! 强制执行)”

    今天网上git下vim的配置后v只要执行:wq就会出现这样的话,找了点资料说是没有.vimbk文件夹,我加了也没用,后来发现在root权限下就不会出现这样的问题,然后我就把当前文件夹下所以的有关vim ...

  4. Yii 安装二维码扩展Qrcode

    比如要添加 https://github.com/2amigos/yii2-qrcode-helper 生成二维码的 这个扩展第一种方法 :    1.打开根目录的composer.json, 在re ...

  5. request对象方法详解

    自己整理的 javax.servlet.http.HttpServletrequest 所有方法,欢迎收藏! 方法名 说明 isUserInRole 判断认证后的用户是否属于某一成员组 getAttr ...

  6. cocos2dx 以子弹飞行为例解说拖尾效果类CCMotionStreak

    在游戏开发中,有时会须要在某个游戏对象上的运动轨迹上实现渐隐效果.比方子弹的运动轨迹,假设不借助引擎的帮助,这样的效果则须要通过大量的图片来实现.而Cocos2D-x的拖动渐隐效果类CCMotionS ...

  7. Android SDK无法更新问题解决

    1.在SDK Manager下Tools->Options打开了SDK Manager的Settings,选中“Force https://… sources to be fetched usi ...

  8. LabVIEW设计模式系列——普遍使用值改变事件

    标准: 1.当使用值改变事件时,使用单击时触发或者单击时释放开关动作.这样即保证仅仅触发一次,也保证按钮恢复默认值 标准:1.值改变事件的优点:不论是鼠标动作还是键盘动作都能触发值改变事件,增强了程序 ...

  9. 注释驱动的 Spring cache 缓存介绍--转载

    概述 Spring 3.1 引入了激动人心的基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如 EHCache 或者 OSCache),而是一个对缓存使 ...

  10. apache kafka源码分析-Producer分析---转载

    原文地址:http://www.aboutyun.com/thread-9938-1-1.html 问题导读1.Kafka提供了Producer类作为java producer的api,此类有几种发送 ...