`

设计模式——迭代器模式

 
阅读更多



  

 

1 初识迭代器模式:

 

定义:提供一种方法来顺序访问一个集合对象中的各个元素,而又不需要暴露该对象的内部表示

结构:



 

 

 注意:  具体集合是放在迭代器实现类内,作为属性和迭代器实现关联, 具体集合仅仅作为一个数据集的作用,迭代器则对数据如何取,内部增加什么过滤或者算法,来实现对具体集合数据的操作,

你可以理解 集合是原木, 迭代器是木匠,木匠可以通过自己的手法(算法)来对原木进行全部获取或者雕刻成什么作品来部分获取

 

参考实现:

 

    迭代器模式调用流程图:

 

使用数组作为基础集合数据来模拟迭代器代码部分:


 

客户端:
public class Client {
	public void someOperation(){
		String[] names = {"张三","李四","王五"};
		Aggregate aggregate = new ConcreteAggregate(names);
		Iterator it = aggregate.createIterator();
		//首先设置迭代器到第一个元素
		it.first();
		while(!it.isDone()){
			Object obj = it.currentItem();
			System.out.println("the obj=="+obj);
			it.next();
		}
	}	
	public static void main(String[] args) {
		Client client = new Client();
		client.someOperation();
	}
}

集合接口:
public abstract class Aggregate {
	/**
	 * 工厂方法,创建相应迭代器对象的接口
	 * @return 相应迭代器对象的接口
	 */
	public abstract Iterator createIterator();
}

集合实现类:
public class ConcreteAggregate extends Aggregate {
	/**
	 * 示意,表示聚合对象具体的内容
	 */
	private String[] ss = null;
	
	/**
	 * 构造方法,传入聚合对象具体的内容
	 * @param ss 聚合对象具体的内容
	 */
	public ConcreteAggregate(String[] ss){
		this.ss = ss;
	}
	
	public Iterator createIterator() {
		//实现创建Iterator的工厂方法
		return new ConcreteIterator(this);
	}
	/**
	 * 获取索引所对应的元素
	 * @param index 索引
	 * @return 索引所对应的元素
	 */
	public Object get(int index){
		Object retObj = null;
		if(index < ss.length){
			retObj = ss[index];
		}
		return retObj;
	}
	/**
	 * 获取聚合对象的大小
	 * @return 聚合对象的大小
	 */
	public int size(){
		return this.ss.length;
	}
}

迭代器接口:
public interface Iterator {
	/**
	 * 移动到聚合对象的第一个位置
	 */
	public void first();
	/**
	 * 移动到聚合对象的下一个位置
	 */
	public void next();
	/**
	 * 判断是否已经移动聚合对象的最后一个位置
	 * @return true表示已经移动到聚合对象的最后一个位置,
	 *         false表示还没有移动到聚合对象的最后一个位置
	 */
	public boolean isDone();
	/**
	 * 获取迭代的当前元素
	 * @return 迭代的当前元素
	 */
	public Object currentItem();
}

迭代器实现类:
public class ConcreteIterator implements Iterator {
	/**
	 * 持有被迭代的具体的聚合对象
	 */
	private ConcreteAggregate aggregate;
	/**
	 * 内部索引,记录当前迭代到的索引位置。
	 * -1表示刚开始的时候,迭代器指向聚合对象第一个对象之前
	 */
	private int index = -1;
	/**
	 * 构造方法,传入被迭代的具体的聚合对象
	 * @param aggregate 被迭代的具体的聚合对象
	 */
	public ConcreteIterator(ConcreteAggregate aggregate) {
		this.aggregate = aggregate;
	}

	public void first(){
		index = 0;
	}
	public void next(){
		if(index < this.aggregate.size()){
			index = index + 1;
		}
	}
	public boolean isDone(){
		if(index == this.aggregate.size()){
			return true;
		}
		return false;
	}
	public Object currentItem(){
		return this.aggregate.get(index);
	}
}

 

 

2 体会迭代器模式:

 

场景问题: 以一个统一方式来访问内部实现不同的聚合对象(子母公司合作统计工资模块案例)

 



 

不使用模式的解决方案: 代码重写,统一成同样实现方式

使用模式的解决方案: 如上图,不同模块因为使用不同具体实现,使用迭代器模式,将原来两个不同的数据

最后用相同的输出框架给框起来。达到统一输出的目的;

 

下面案例调用流程 请参看: 上面的 <迭代器模式调用流程图>  唯一的区别就是:

集合实现类 变成了两个,一个是PayManager, 一个是SalaryManager:

代码如下: 使用迭代器模式 给不同具体实现套上不同壳子,壳子里面是每个具体实现的具体写法,但是暴露给客户端的 将是同样的壳子

 

不使用迭代器模式下 客户端调用写法,次写法无法将工资输出统一起来:
public class Client {
	public static void main(String[] args) {
		//访问集团的工资列表
		PayManager payManager= new PayManager();
		//先计算再获取
		payManager.calcPay();
		Collection payList = payManager.getPayList();
		Iterator it = payList.iterator();
		System.out.println("集团工资列表:");
		while(it.hasNext()){
			PayModel pm = (PayModel)it.next();
			System.out.println(pm);
		}
		
		//访问新收购公司的工资列表
		SalaryManager salaryManager = new SalaryManager();
		//先计算再获取
		salaryManager.calcSalary();
		PayModel[] pms = salaryManager.getPays();
		System.out.println("新收购的公司工资列表:");
		for(int i=0;i<pms.length;i++){
			System.out.println(pms[i]);
		}
	}
}

使用迭代器模式下 客户端写法:

public class Client {
	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 interface Iterator {
	
	public void first();
	
	public void next();
	
	public boolean isDone();
	
	public Object currentItem();
}

迭代器实现类之针对数组:
public class ArrayIteratorImpl implements Iterator{
	/**
	 * 用来存放被迭代的聚合对象
	 */
	private SalaryManager aggregate = null;

	private int index = -1;
	
	public ArrayIteratorImpl(SalaryManager aggregate){
		this.aggregate = aggregate;
	}
	
	
	public void first(){
		index = 0;
	}
	public void next(){
		if(index < this.aggregate.size()){
			index = index + 1;
		}
	}
	public boolean isDone(){
		if(index == this.aggregate.size()){
			return true;
		}
		return false;
	}
	public Object currentItem(){
		return this.aggregate.get(index);
	}
}


迭代器实现类之针对 集合:

public class CollectionIteratorImpl implements Iterator{
	/**
	 * 用来存放被迭代的聚合对象
	 */
	private PayManager aggregate = null;
	
	private int index = -1;
	
	public CollectionIteratorImpl(PayManager aggregate){
		this.aggregate = aggregate;
	}
	
	public void first(){
		index = 0;
	}
	public void next(){
		if(index < this.aggregate.size()){
			index = index + 1;
		}
	}
	public boolean isDone(){
		if(index == this.aggregate.size()){
			return true;
		}
		return false;
	}
	public Object currentItem(){
		return this.aggregate.get(index);
	}
}

数据集合接口:
public abstract class Aggregate {
	/**
	 * 工厂方法,创建相应迭代器对象的接口
	 * @return 相应迭代器对象的接口
	 */
	public abstract Iterator createIterator();
}

数据集合实现类之针对 集合:
public 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 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;
	}
}

PayModel:
public 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;
	}
}

 

 

3 理解迭代器模式:

 

 迭代器的关键思想: 把聚合对象的遍历和访问从聚合对象中分离出来,放入到单独迭代器中,这样迭代器和聚合对象可以独立变化和发展,提高系统灵活性;

 

 使用Java迭代器:使用javase提供的Iterator 取代我们自定义类Iterator, 其余不变

 

带迭代策略的迭代器:因为迭代和访问数据的分离,因此在迭代中可以增加策略,比如 实现过滤,

  对数据进行整条过滤,只能查看自己部门的数据;

  对数据进行部分过滤,比如某人不能查看工资数据;

 

如下即 表示能在迭代器中增加算法  又能增加过滤功能,增加算法后新的数据集合来取代原有数据集合

public ArrayIteratorImpl(SalaryManager aggregate){
		//在这里先对聚合对象的数据进行过滤,比如工资必须在3000以下
		Collection<PayModel> tempCol = new ArrayList<PayModel>();
		for(PayModel pm : aggregate.getPays()){
			if(pm.getPay() < 3000){
				tempCol.add(pm);
			}
		}
		//然后把符合要求的数据存放到用来迭代的数组
		this.pms = new PayModel[tempCol.size()];
		int i=0;
		for(PayModel pm : tempCol){
			this.pms[i] = pm;
			i++;
		}
	}

 

 

 

双向迭代器:同时向前或者向后遍历数据的迭代器  eg:" java.util.ListIterator

 

优缺点:

 

4 思考迭代器模式:

 

本质:控制+访问 ---> 聚合对象中的元素

何时选用:

a) 访问聚合对象的同时不像暴露此对象的内部时

b) 为遍历不同聚合对象提供一个统一接口时

c) 期待以多种方式访问聚合对象时(比如 向后访问, 向前访问, 间隔一个方式访问)


 

 

 

5 迭代器脑图:

 

 



 

 

 

 

 

 

 

  • 大小: 89.1 KB
  • 大小: 25.9 KB
  • 大小: 23.4 KB
分享到:
评论

相关推荐

    详解Java设计模式——迭代器模式

    主要介绍了Java设计模式——迭代器模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    Python设计模式之迭代器模式原理与用法实例分析

    本文实例讲述了Python设计模式之迭代器模式原理...设计模式——迭代器模式 迭代器模式(Iterator Pattern):提供方法顺序访问一个聚合对象中各元素,而又不暴露该对象的内部表示. """ #迭代器抽象类 class Iterator(objec

    设计模式(十七)——迭代器模式(Iterator Pattern)

    迭代器模式(Iterator Pattern) 基本介绍 迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。 提供一种可以遍历聚合对象的方式。又...

    Java设计模式 版本2

    设计模式之代理模式,请求的链式处理——职责链模式,请求发送者与接收者解耦——命令模式,自定义语言的实现——解释器模式,遍历聚合对象中的元素——迭代器模式,协调多个对象之间的交互——中介者模式,撤销功能...

    设计模式可复用面向对象软件的基础.zip

    5.4 ITERATOR(迭代器)—对象行为型 模式 171 5.5 MEDIATOR(中介者)—对象行为型 模式 181 5.6 MEMENTO(备忘录)—对象行为型 模式 188 5.7 OBSERVER(观察者)—对象行为型 模式 194 5.8 STATE(状态)—对象...

    设计模式——基于 C#的工程化实现及扩展(部分章节)

    电子书 目 录 导读 .............................................................................1.2.6 融入C#语言的迭代机制——迭代器(Iterator ) .................................................... 29

    设计模式代码——c#

    15. 迭代器模式(Iterator Pattern) 16. 观察者模式(Observer Pattern) 17. 解释器模式(Interpreter Pattern) 18. 中介者模式(Mediator Pattern) 19. 职责链模式(Chain of Responsibility Pattern) 20. ...

    design-pattern-java.pdf

    自定义语言的实现——解释器模式(五) 自定义语言的实现——解释器模式(六) 迭代器模式-Iterator Pattern 遍历聚合对象中的元素——迭代器模式(一) 遍历聚合对象中的元素——迭代器模式(二) 遍历聚合对象中的...

    深入理解JavaScript系列.chm

    35.设计模式之迭代器模式 36.设计模式之中介者模式 37.设计模式之享元模式 38.设计模式之职责链模式 39.设计模式之适配器模式 40.设计模式之组合模式 41.设计模式之模板方法 42.设计模式之原型模式 43.设计模式之...

    深入浅出设计模式(中文版)

    5.4IteratorPattern(迭代器模式) 205 5.4.1定义 205 5.4.2现实示例——电视节目选择器 206 5.4.3C#实例——遍历例子 207 5.4.4Java实例——两个迭代器 211 5.4.5优势和缺陷 213 5.4.6应用情景 214 5.5...

    深入浅出设计模式(中文版电子版)

    5.4IteratorPattern(迭代器模式) 205 5.4.1定义 205 5.4.2现实示例——电视节目选择器 206 5.4.3C#实例——遍历例子 207 5.4.4Java实例——两个迭代器 211 5.4.5优势和缺陷 213 5.4.6应用情景 214 5.5...

    java设计模式

    20.3 迭代器模式的应用 20.4 最佳实践 第21章 组合模式 21.1 公司的人事架构是这样的吗 21.2 组合模式的定义 21.3 组合模式的应用 21.3.1 组合模式的优点 21.3.2 组合模式的缺点 21.3.3 组合模式的应用 21.3.4 组合...

    java和设计模式ppt教程

    java和设计模式ppt包含工厂模式、建造模式、原始模型模式、单例模式、结构模式、适配器、桥梁模式、合成模式、装饰模式、门面模式、享元模式、代理模式、行为模式、解释器模式、迭代子模式、调停者模式、备忘录模式...

    设计模式--可复用面向对象软件的基础

    5.4 ITERATOR(迭代器)——对象行为型模式 5.5 MEDIATOR(中介者)——对象行为型模式 5.6 MEMENTO(备忘录)——对象行为型模式 5.7 OBSERVER(观察者)——对象行为型模式 5.8 STATE(状态)——对象行为型模式 ...

    24种设计模式介绍与6大设计原则

    行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 二、设计模式的六大原则 1、开闭原则(Open Close...

    JavaScript模式中文[pdf] 百度云

     迭代器模式  装饰者模式  策略模式  外观模式  代理模式  中介者模式  观察者模式  小结  第8章 DOM和浏览器模式  关注分离  DOM脚本  事件  长期运行脚本  远程脚本  配置JavaScript  载入策略

    Python学习笔记(五)——–Python迭代器

    迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。 关键点:遍访(遍历?)容器 二、迭代器特点 1.迭代器可以...

    设计模式Demo

    行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 其实还有两类:并发型模式和线程池模式。 二、设计...

    C#23种设计模式_示例源代码及PDF

    解释器模式将描述怎样 在 有了一个简单的文法后, 使用模式设计解释这些语句。 在解释器模式里面提到的语言是指任 何解释器对象能够解释的任何组合。在解释器模式中需要定义一个代表 文法的命令类的等 级结构,也...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷6

    综合实例——Bug管理系统 (3)设计模式样例(24个讲解样例程序) pattern/src/principle/liskovsubstitution//10.3.2里氏代换原则 pattern/src/creation/factorymethod //11.1工厂方法模式 pattern/src/creation/...

Global site tag (gtag.js) - Google Analytics