行为类模式(四):迭代器(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 ...
随机推荐
- 1388:Lake Counting
题目链接: NOI题库http://noi.openjudge.cn/ch0205/1388/ POJ 2386 http://poj.org/problem?id=2386 总时间限制: 1000m ...
- Citrix Port(常用端口)
组件 类型 端口 描述 CitrixLicenseServer 许可管理器守护程序 TCP 27000 处理初始接触点的许可证要求(Lmadmin.exe) 思杰供应商守护程序 TCP 7 ...
- [转载]ubuntu防火墙设置
原文地址:ubuntu防火墙设置作者:風飏 自打2.4版本以后的Linux内核中, 提供了一个非常优秀的防火墙工具.这个工具可以对出入服务的网络数据进行分割.过滤.转发等等细微的控制,进而实现诸 ...
- IP首部格式[转载]
TCP 传输首部是 IP首部,所以把IP首部格式 拿过来研究下,看IP首部解码过程: 来源:51CTO博客,地址:http://lihuan.blog.51cto.com/4391550/7999 ...
- Mysql5.6 make 错误以及解决办法
1.若make出现类似错误: CMake Error: CMake was unable to find a build program corresponding to "Unix Mak ...
- React(0.13) 服务端渲染的两个函数
1.React.renderToString 函数, 参数是组件,返回一个字符串 <!DOCTYPE html> <html> <head> <title& ...
- JAVA基本值类型
Java定义了8个简单(或基本)的数据类型:------------------------------------------------------字节型(byte),短整型(short),整型( ...
- apk 静默安装
老大要我弄个自动更新,要用到静默安装,网上找到了些大拿的代码,我拿去改吧改吧,先贴出来: /** * 软件静默安装 * @param apkAbsolutePath apk文件所在路径 * @retu ...
- Spring 注解 hibernate 实体方法 <property name="packagesToScan" value="com.sise.domain"/>
<property name="annotatedClasses"> <list> <value>com.sise.domain.Admin&l ...
- NPM Node.js 包管理
1.NPM 简介 1.1 NPM Node.js® 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,可方便地构建快速,可扩展的网络应用程序的平台.Node.js 使用事件驱动, ...