行为类模式(四):迭代器(Iterator)
定义
提供一种方法访问一个容器(container)对象中的各个元素,而又不暴露该对象的内部细节。
UML

优点
- 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
- 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
- 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。
缺点
- 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合,操作简易度完爆迭代。
应用场景
- 迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。
- 但是,由于容器与迭代器的关系太密切了,所以大多数语言在实现容器的时候都给提供了迭代器,并且这些语言提供的容器和迭代器在绝大多数情况下就可以满足我们的需要,所以现在需要我们自己去实践迭代器模式的场景还是比较少见的,我们只需要使用语言中已有的容器和迭代器就可以了。
示例
考虑这样一个需求,一家大公司合并了一家小公司,而两家公司的工资系统不一样,大公司使用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)的更多相关文章
- 设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释
迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(ite ...
- JAVA之旅(十八)——基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用
JAVA之旅(十八)--基本数据类型的对象包装类,集合框架,数据结构,Collection,ArrayList,迭代器Iterator,List的使用 JAVA把完事万物都定义为对象,而我们想使用数据 ...
- 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)
设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...
- 行为型模式(三) 迭代器模式(Iterator)
一.动机(Motivate) 在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素:同时这种"透明 ...
- Java 实现迭代器(Iterator)模式
类图 /** * 自己定义集合接口, 相似java.util.Collection * 用于数据存储 * @author stone * */ public interface ICollection ...
- 设计模式 - 组合模式(composite pattern) 迭代器(iterator) 具体解释
组合模式(composite pattern) 迭代器(iterator) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考组合模式(composit ...
- 1、迭代器 Iterator模式 一个一个遍历 行为型设计模式
1.Iterator模式 迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或者阵列)上遍访的接口,设计人员无需关心容器的内容. I ...
- 十一个行为模式之迭代器模式(Iterator Pattern)
定义: 提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示.使得存储和遍历两个职责相互分离,提高系统的可扩展性. 结构图: Iterator:抽象迭代器类,定义了访问和遍历元素的接口,例如:ne ...
- java基础知识5--集合类(Set,List,Map)和迭代器Iterator的使用
写的非常棒的一篇总结: http://blog.csdn.net/speedme/article/details/22398395#t1 下面主要看各个集合如何使用迭代器Iterator获取元素: 1 ...
- Python进阶内容(四)--- 迭代器(Iterator)与生成器(Generator)
迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的ge ...
随机推荐
- python之模块cmath
# -*- coding: utf-8 -*-#python 27#xiaodeng#python之模块cmath #复数的数学函数,如log.tan.sin等函数用法,针对我目前的情况用途较少,暂不 ...
- Dlib三维点云示例
Dlib三维点云示例 源代码来自Dlib的示例代码http://dlib.net/3d_point_cloud_ex.cpp.html 在windows下需要链接winmm``comctl32``gd ...
- 一种通过MQ使缓存和数据库同步的玩法
其他相关玩法 可以搜索 mysql 和 redis 结合使用
- Linux 防火墙Iptables
1.规则链INPUT——进来的数据包应用此规则链中的策略OUTPUT——外出的数据包应用此规则链中的策略FORWARD——转发数据包时应用此规则链中的策略PREROUTING——对数据包作路由选择前应 ...
- Dapper 的输出参数使用示范
-- 普通SQL 示范-- Queries with output parameters. Hide Shrink Copy Code // output parameters // the para ...
- ios中tableview网封装(viewcontroller封装)常用的
下载地址 http://pan.baidu.com/share/link?shareid=3657500168&uk=923776187 使用框架 1:asIHttpRequest库 2;SB ...
- mvn jetty debug
使用mvn jetty:run很爽吧,但是怎么debug了,找了Google的N多老外文章,终于可以了,文章链接:http://gaertig.pl/blog/en/2009/03/debug-jet ...
- 利用hadoop来解决“共同好友”的问题
假设A有好友B C D:B有好友A C D E:C有好友A B D E:D有好友A B C E;E有好友B C D. A -> B C D B -> A C D E C -> A B ...
- TensorFlow Google大会总结
一.概述 介绍TPU,需要使用XLA编译,否则没有做内部优化,无法达到加速的效果: TPU相关的性能分析器: 二.新版本的输入库 之前TensorFlow的输入方式: feed_dict: 太过于低效 ...
- 【Android】播放音频的几种方式介绍
接下来笔者介绍一下Android中播放音频的几种方式,android.media包下面包含了Android开发中媒体类,当然笔者不会依次去介绍,下面介绍几个音频播放中常用的类: 1.使用MediaPl ...