定义

提供一种方法访问一个容器(container)对象中的各个元素,而又不暴露该对象的内部细节。

UML

优点

  1. 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
  2. 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
  3. 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。

缺点

  1. 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合,操作简易度完爆迭代。

应用场景

  1. 迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。
  2. 但是,由于容器与迭代器的关系太密切了,所以大多数语言在实现容器的时候都给提供了迭代器,并且这些语言提供的容器和迭代器在绝大多数情况下就可以满足我们的需要,所以现在需要我们自己去实践迭代器模式的场景还是比较少见的,我们只需要使用语言中已有的容器和迭代器就可以了。

示例

考虑这样一个需求,一家大公司合并了一家小公司,而两家公司的工资系统不一样,大公司使用List记录员工工资,小公司使用数组记录员工工资,而这两个不一样的工资系统需要合并进行查询所有人的工资,且需要打印出相同的结果时,我们可以使用迭代器模式来解决这个问题。

Java

 import java.util.ArrayList;
import java.util.List; public class Main
{
public static void main(String[] args)
{
//访问集团的工资列表
PayManager payManager = new PayManager();
//先计算再获取
payManager.calcPay();
System.out.println("集团工资列表:");
test(payManager.createIterator()); //访问新收购公司的工资列表
SalaryManager salaryManager = new SalaryManager();
//先计算再获取
salaryManager.calcSalary();
System.out.println("新收购的公司工资列表:");
test(salaryManager.createIterator());
} private static void test(Iterator it)
{
it.first();
while (!it.isDone())
{
Object obj = it.currentItem();
System.out.println("the obj==" + obj);
it.next();
}
} /**
* 工资模型
*/
public static class PayModel
{
/**
* 支付工资的人员
*/
private String userName; /**
* 支付的工资数额
*/
private double pay; public String getUserName()
{
return userName;
} public void setUserName(String userName)
{
this.userName = userName;
} public double getPay()
{
return pay;
} public void setPay(double pay)
{
this.pay = pay;
} public String toString()
{
return "userName=" + userName + ", pay=" + pay;
}
} /**
* 大公司员工工资管理器
*/
public static class PayManager extends Aggregate
{
/**
* 聚合对象,这里是Java的集合对象
*/
private List list = new ArrayList(); public List getPayList()
{
return list;
} public void calcPay()
{
PayModel pm1 = new PayModel();
pm1.setPay(3800);
pm1.setUserName("张三"); PayModel pm2 = new PayModel();
pm2.setPay(5800);
pm2.setUserName("李四"); list.add(pm1);
list.add(pm2);
} public Iterator createIterator()
{
return new CollectionIteratorImpl(this);
} public Object get(int index)
{
Object retObj = null;
if (index < this.list.size())
{
retObj = this.list.get(index);
}
return retObj;
} public int size()
{
return this.list.size();
}
} /**
* 小公司员工工资管理器
*/
public static class SalaryManager extends Aggregate
{
/**
* 用数组管理
*/
private PayModel[] pms = null; public PayModel[] getPays()
{
return pms;
} public void calcSalary()
{
//计算工资,并把工资信息填充到工资列表里面
//为了测试,做点假数据进去
PayModel pm1 = new PayModel();
pm1.setPay(2200);
pm1.setUserName("王五"); PayModel pm2 = new PayModel();
pm2.setPay(3600);
pm2.setUserName("赵六"); pms = new PayModel[2];
pms[0] = pm1;
pms[1] = pm2;
} public Iterator createIterator()
{
return new ArrayIteratorImpl(this);
} public Object get(int index)
{
Object retObj = null;
if (index < pms.length)
{
retObj = pms[index];
}
return retObj;
} public int size()
{
return this.pms.length;
}
} /**
* 集合接口
*/
public static abstract class Aggregate
{
/**
* 工厂方法,创建相应迭代器对象的接口
* @return 相应迭代器对象的接口
*/
public abstract Iterator createIterator();
} /**
* 迭代器接口
*/
public interface Iterator
{
void first(); void next(); boolean isDone(); Object currentItem();
} /**
* 数组迭代器
*/
public static class ArrayIteratorImpl implements Iterator
{
/**
* 用来存放被迭代的聚合对象
*/
private SalaryManager aggregate = null; private int index = -1; public ArrayIteratorImpl(SalaryManager aggregate)
{
this.aggregate = aggregate;
} @Override
public void first()
{
index = 0;
} @Override
public void next()
{
if (index < this.aggregate.size())
{
index = index + 1;
}
} @Override
public boolean isDone()
{
if (index == this.aggregate.size())
{
return true;
}
return false;
} @Override
public Object currentItem()
{
return this.aggregate.get(index);
}
} /**
* 集合列表迭代器
*/
public static class CollectionIteratorImpl implements Iterator
{
/**
* 用来存放被迭代的聚合对象
*/
private PayManager aggregate = null; private int index = -1; public CollectionIteratorImpl(PayManager aggregate)
{
this.aggregate = aggregate;
} @Override
public void first()
{
index = 0;
} @Override
public void next()
{
if (index < this.aggregate.size())
{
index = index + 1;
}
} @Override
public boolean isDone()
{
if (index == this.aggregate.size())
{
return true;
}
return false;
} @Override
public Object currentItem()
{
return this.aggregate.get(index);
}
}
}

行为类模式(四):迭代器(Iterator)的更多相关文章

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

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

  2. JAVA之旅(十八)——基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用

    JAVA之旅(十八)--基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用 JAVA把完事万物都定义为对象,而我们想使用数据 ...

  3. 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)

      设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...

  4. 行为型模式(三) 迭代器模式(Iterator)

    一.动机(Motivate) 在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素:同时这种"透明 ...

  5. Java 实现迭代器(Iterator)模式

    类图 /** * 自己定义集合接口, 相似java.util.Collection * 用于数据存储 * @author stone * */ public interface ICollection ...

  6. 设计模式 - 组合模式(composite pattern) 迭代器(iterator) 具体解释

    组合模式(composite pattern) 迭代器(iterator) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考组合模式(composit ...

  7. 1、迭代器 Iterator模式 一个一个遍历 行为型设计模式

    1.Iterator模式 迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或者阵列)上遍访的接口,设计人员无需关心容器的内容. I ...

  8. 十一个行为模式之迭代器模式(Iterator Pattern)

    定义: 提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示.使得存储和遍历两个职责相互分离,提高系统的可扩展性. 结构图: Iterator:抽象迭代器类,定义了访问和遍历元素的接口,例如:ne ...

  9. java基础知识5--集合类(Set,List,Map)和迭代器Iterator的使用

    写的非常棒的一篇总结: http://blog.csdn.net/speedme/article/details/22398395#t1 下面主要看各个集合如何使用迭代器Iterator获取元素: 1 ...

  10. Python进阶内容(四)--- 迭代器(Iterator)与生成器(Generator)

    迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的ge ...

随机推荐

  1. CentOS 7 修改网卡名

    假设原网卡名为eth1, 那么在 /etc/sysconfig/network-scripts/ 目录下,必定会存在一个文件名为ifcfg-eth1,和网卡名对应, 这里假设要修改为eth0. 方法一 ...

  2. Centos6.x 设置终端超时, 加强用户密码策略

    1. 密码有效期, 密码长度 $ more /etc/login.defs # Password aging controls: # # PASS_MAX_DAYS Maximum number of ...

  3. [Spring学习笔记 3 ] spring 注解详解,完全注解,常用注解

    .xml使用注解 xml 用来定义bean的信息,注解用来配置依赖信息 ) 在配置文件中配置bean )在javaBean中用注解来指定依赖注入 )在配置文件中开启注解扫描 @Resource标签 j ...

  4. 如何从windows中拷贝文件到linux (ubuntu)??

    安装ssh,然后用客户端似的界面远程手动拖动即可.

  5. Linux按照CPU、内存、磁盘IO、网络性能监测【转载】

    本文转载地址:https://my.oschina.net/chape/blog/159640 系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监 ...

  6. MYSQL-innodb性能优化几个点

    MYSQL-innodb性能优化几个点 数据库常用参数 MYSQL数据库的参数配置一般在my.ini配置(部分参数也可以用set  global 参数名=值 做临时调整,重启后失效),配置完后需要重启 ...

  7. HDU 3584 Cube (三维数状数组)

    Cube Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submi ...

  8. PHP中使用 JKS(Java Key Store)的方法

    PHP语言无法直接读取 JKS中的密钥,需要通过以下方法进行转换 本例以JKS中的私钥为例 首先 使用 KeyStore Explorer工具,打开JKS文件 ,此时可能需要输入 JKS密码 对私钥进 ...

  9. aaronyang的百度地图API之LBS云与.NET开发 Javascript API 2.0【把数据存到LBS云1/2】

    如何让用户点,我们可以获得经纬度,我们就要先了解下它给我们提供的百度地图的事件 主要有两个操作事件的,绑定(addEventListener)和解绑(removeEventListener) 一些事件 ...

  10. sql server 2008评估期已到的解决办法

    点击开始-所有程序-Microsoft SQL Server 2008-配置工具-SQL Server 安装中心然后点击左侧的维护,在点击右侧的版本升级,接着按照提示一直点下一步,到产品密钥的时候输入 ...