定义

提供一种方法访问一个容器(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. C++高性能转换大小写算法

    简述 有一个需求,是需要将URL中的query参数的key全部转换为小写或者大写,键值对的数量有点多,但全部都是英文字母,无需考虑非字母的情况. 实现比较快的做法是使用STL或C标准库中的转换接口,如 ...

  2. Windows下 VS2015编译ForestDB

    VS2015编译ForestDB ForestDB 是一个快速的 Key-Value 存储引擎,基于层次B +树单词查找树.由 Couchbase 缓存和存储团队开发. 1.下载forestdb源码 ...

  3. N皇后问题【递归求解】

    n皇后问题:输入整数n, 要求n个国际象棋的皇后,摆在n*n的棋盘上,互相不能攻击,输出全部方案. 输入一个正整数N,则程序输出N皇后问题的全部摆法.输出结果里的每一行都代表一种摆法.行里的第i个数字 ...

  4. Jenkins执行批处理文件失败

    今天搭建Jenkins持续集成环境,编译环境是.net,在.net下没有比较好的代码覆盖率测试插件,所以用了开源的OpenCover,计算代码覆盖率,然后用ReportGenerator导出hmtl格 ...

  5. PLSQL创建DBLINK

    Oracle创建dblink,多用于数据的同步机制.不建议直接用dblink对数据库频繁的操作... 00.查看创建dblink权限 select * from user_sys_privs t wh ...

  6. 开源分布式搜索平台ELK(Elasticsearch+Logstash+Kibana)入门学习资源索引

    from:  http://www.w3c.com.cn/%E5%BC%80%E6%BA%90%E5%88%86%E5%B8%83%E5%BC%8F%E6%90%9C%E7%B4%A2%E5%B9%B ...

  7. Android Intent之Action应用

    Log.i("txrjsms", "whereDoYouJumpFrom:"+getIntent().getPackage()); 结果是null Log.i( ...

  8. 禁止logback输出状态信息

    一.问题描述 22:18:07,299 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resourc ...

  9. 在 Linux 平台中调试 C/C++ 内存泄漏方法(转)

    由于 C 和 C++ 程序中完全由程序员自主申请和释放内存,稍不注意,就会在系统中导入内存错误.同时,内存错误往往非常严重,一般会带来诸如系统崩溃,内存耗尽这样严重的后果.本文将从静态分析和动态检测两 ...

  10. 【MyBatis】MyBatis之别名typeAliases标签的使用

    <configuration> <typeAliases> <typeAlias alias="Dept" type="cn.xdl.ent ...