`

设计模式——迭代器模式

 
阅读更多



  

 

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设计模式——迭代器模式 迭代器模式是Java设计模式的一种,主要用于解决聚合对象的遍历问题。该模式提供了一种方法顺序访问一个聚合对象中的各个元素,而又无须暴露该对象的内部表示。通过使用迭代器模式,...

    Android编程设计模式之迭代器模式详解

    迭代器模式是指在客户访问类与容器体之间插入了一个第三者——迭代器,以解决容器类承担了过多的功能和遍历状态的存储问题。迭代器模式可以让容器类专注于维护自身内部的数据元素,而将遍历的方法封装在迭代器中,...

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

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

    设计模式——GFour

    行为型模式主要关注对象间职责的分配和通信,包括责任链模式、命令模式、解释器模式、迭代器模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。这些模式有助于我们更好地管理对象的行为...

    设计模式——原版的设计模式

    迭代器模式提供了一个方法来顺序访问聚合对象的元素,而又不暴露其底层表示;模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中;备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在...

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

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

    JAVA 设计模式 工厂模式 代理模式 迭代模式 责任链模式 源码

    以下是关于JAVA设计模式中提及的四种模式——工厂模式、代理模式、迭代器模式以及责任链模式的详细说明。 1. **工厂模式**:工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,当创建...

    设计模式之美——教你写出高质量代码

    3. 行为型模式:如策略模式、模板方法模式、观察者模式、命令模式、迭代器模式、责任链模式、备忘录模式、状态模式、解释器模式和访问者模式。这些模式主要处理对象之间的通信和行为,让代码更易于理解和扩展。 在...

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

    ### 设计模式——基于C#的工程化实现及扩展 #### 第一部分:预备知识——发掘用C#语言进行面向对象化设计的潜力 ##### 第1章 重新研读C#语言 **1.1 说明** 本章旨在帮助读者更好地理解和掌握C#语言的核心特性...

    设计模式——JAVA.docx

    - **行为型模式**(共11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 每一种设计模式都有其特定的应用场景和解决的...

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

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

    JAVA迭代器模式.pptx

    迭代器模式通过将迭代逻辑封装在一个独立的对象——迭代器中,解决了上述问题。这样做的好处包括: 1. **功能分离**:将遍历逻辑从容器中分离出来,使得容器只需关注其核心功能,即存储和管理元素,而遍历则交由...

    23种 设计模式---面向对象的基本原则

    - 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):用一个中介对象来封装一系列的对象交互,降低系统的耦合度。 - 备忘录模式(Memento):在不...

    《java设计模式》课后习题模拟试题解答——刘伟.zip

    本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...

    C#面向对象设计模式纵横谈(18):(行为型模式) Iterator 迭代器模式 (Level 300)

    迭代器模式是面向对象设计中的一个行为型模式,它的主要目的是提供一种方法来顺序访问聚合对象的元素,而又不暴露其底层表示。在C#中,迭代器模式的应用广泛且重要,尤其对于集合类的遍历操作至关重要。本文将深入...

Global site tag (gtag.js) - Google Analytics