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 迭代器脑图:
相关推荐
详解Java设计模式——迭代器模式 迭代器模式是Java设计模式的一种,主要用于解决聚合对象的遍历问题。该模式提供了一种方法顺序访问一个聚合对象中的各个元素,而又无须暴露该对象的内部表示。通过使用迭代器模式,...
迭代器模式是指在客户访问类与容器体之间插入了一个第三者——迭代器,以解决容器类承担了过多的功能和遍历状态的存储问题。迭代器模式可以让容器类专注于维护自身内部的数据元素,而将遍历的方法封装在迭代器中,...
本文实例讲述了Python设计模式之迭代器模式原理...设计模式——迭代器模式 迭代器模式(Iterator Pattern):提供方法顺序访问一个聚合对象中各元素,而又不暴露该对象的内部表示. """ #迭代器抽象类 class Iterator(objec
行为型模式主要关注对象间职责的分配和通信,包括责任链模式、命令模式、解释器模式、迭代器模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。这些模式有助于我们更好地管理对象的行为...
迭代器模式提供了一个方法来顺序访问聚合对象的元素,而又不暴露其底层表示;模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中;备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在...
迭代器模式(Iterator Pattern) 基本介绍 迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。 提供一种可以遍历聚合对象的方式。又...
以下是关于JAVA设计模式中提及的四种模式——工厂模式、代理模式、迭代器模式以及责任链模式的详细说明。 1. **工厂模式**:工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,当创建...
3. 行为型模式:如策略模式、模板方法模式、观察者模式、命令模式、迭代器模式、责任链模式、备忘录模式、状态模式、解释器模式和访问者模式。这些模式主要处理对象之间的通信和行为,让代码更易于理解和扩展。 在...
### 设计模式——基于C#的工程化实现及扩展 #### 第一部分:预备知识——发掘用C#语言进行面向对象化设计的潜力 ##### 第1章 重新研读C#语言 **1.1 说明** 本章旨在帮助读者更好地理解和掌握C#语言的核心特性...
- **行为型模式**(共11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 每一种设计模式都有其特定的应用场景和解决的...
5.4 ITERATOR(迭代器)—对象行为型 模式 171 5.5 MEDIATOR(中介者)—对象行为型 模式 181 5.6 MEMENTO(备忘录)—对象行为型 模式 188 5.7 OBSERVER(观察者)—对象行为型 模式 194 5.8 STATE(状态)—对象...
迭代器模式通过将迭代逻辑封装在一个独立的对象——迭代器中,解决了上述问题。这样做的好处包括: 1. **功能分离**:将遍历逻辑从容器中分离出来,使得容器只需关注其核心功能,即存储和管理元素,而遍历则交由...
- 迭代器模式(Iterator):提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。 - 中介者模式(Mediator):用一个中介对象来封装一系列的对象交互,降低系统的耦合度。 - 备忘录模式(Memento):在不...
本资料“《java设计模式》课后习题模拟试题解答——刘伟.zip”主要涵盖了Java设计模式的学习与应用,特别是针对刘伟教授的相关课程的课后习题及模拟试题的解答。 设计模式分为三大类:创建型、结构型和行为型模式。...
迭代器模式是面向对象设计中的一个行为型模式,它的主要目的是提供一种方法来顺序访问聚合对象的元素,而又不暴露其底层表示。在C#中,迭代器模式的应用广泛且重要,尤其对于集合类的遍历操作至关重要。本文将深入...