大话设计模式笔记(十七)の迭代器模式

迭代器模式

定义

提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

什么时候用?

  • 当你需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式
  • 你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。

UML图

模板代码

Aggregate

/**
 * 聚集抽象类
 * Created by callmeDevil on 2019/8/17.
 */
public abstract class Aggregate {
    // 创建迭代器
    public abstract Iterator createIterator();
}

Iterator

/**
 * 迭代器抽象类
 * Created by callmeDevil on 2019/8/17.
 */
public abstract class Iterator {
    // 用于定义得到开始对象、得到下一对象、判断是否到结尾、当前对象等抽象方法
    public abstract Object first();
    public abstract Object next();
    public abstract boolean isDone();
    public abstract Object currentItem();
}

ConcreteAggregate

/**
 * 具体聚集类
 * Created by callmeDevil on 2019/8/17.
 */
public class ConcreteAggregate extends Aggregate {

    // 存放聚合对象
    private List<Object> items = new ArrayList();

    @Override
    public Iterator createIterator() {
        return new ConcreteIterator(this);
    }

    // 返回聚集的总个数
    public int count() {
        return items.size();
    }

    // 声明一个索引器
    public Object get(int index) {
        return items.get(index);
    }
    public boolean set(Object o) {
        return items.add(o);
    }

}

ConcreteIterator

/**
 * 具体迭代器类
 * Created by callmeDevil on 2019/8/17.
 */
public class ConcreteIterator extends Iterator {

    // 定义一个具体聚集对象
    private ConcreteAggregate aggregate;
    private int current = 0;

    public ConcreteIterator(ConcreteAggregate aggregate){
        // 初始化时将具体的聚集对象传入
        this.aggregate = aggregate;
    }

    @Override
    public Object first() {
        // 得到聚集的第一个对象
        return aggregate.get(0);
    }

    @Override
    public Object next() {
        Object ret = null;
        current++;
        if (current < aggregate.count()) {
            // 得到聚集的下一个对象
            ret = aggregate.get(current);
        }
        return ret;
    }

    @Override
    public boolean isDone() {
        // 判断当前是否遍历到结尾
        return current >= aggregate.count();
    }

    @Override
    public Object currentItem() {
        // 返回当前的聚集对象
        return aggregate.get(current);
    }

}

测试

public class Test {
    public static void main(String[] args) {
        // 公交车聚集对象
        ConcreteAggregate a = new ConcreteAggregate();
        // 新上来的乘客
        a.set("路飞");
        a.set("鸣人");
        a.set("一护");
        a.set("悟空");
        a.set("纳兹");
        a.set("琦玉");
        // 售票员登场,看好上车的是哪些人,即声明迭代器对象
        Iterator i = new ConcreteIterator(a);
        System.out.println(String.format("车位No.1乘客:%s", i.first()));
        while (!i.isDone()){
            System.out.println(String.format("%s 来不及解释了,快上车!", i.currentItem()));
            i.next();
        }
    }
}

测试结果

车位No.1乘客:路飞
路飞 来不及解释了,快上车!
鸣人 来不及解释了,快上车!
一护 来不及解释了,快上车!
悟空 来不及解释了,快上车!
纳兹 来不及解释了,快上车!
琦玉 来不及解释了,快上车!

倒序遍历

ConcreteIteratorDesc

/**
 * 倒序具体迭代器
 * Created by callmeDevil on 2019/8/17.
 */
public class ConcreteIteratorDesc extends Iterator{

    // 定义一个具体聚集对象
    private ConcreteAggregate aggregate;
    private int current = 0;

    public ConcreteIteratorDesc(ConcreteAggregate aggregate){
        // 初始化时将具体的聚集对象传入
        this.aggregate = aggregate;
        current = aggregate.count() - 1;  //不同1
    }

    @Override
    public Object first() {
        // 得到聚集的第一个对象
        return aggregate.get(aggregate.count() - 1); //不同2
    }

    @Override
    public Object next() {
        Object ret = null;
        current--;  //不同3
        if (current >= 0) {  //不同4
            // 得到聚集的下一个对象
            ret = aggregate.get(current);
        }
        return ret;
    }

    @Override
    public boolean isDone() {
        // 判断当前是否遍历到结尾
        return current < 0;  //不同5
    }

    @Override
    public Object currentItem() {
        // 返回当前的聚集对象
        return aggregate.get(current);
    }

}

测试

将顺序测试类中声明迭代器具体对象改为倒序的 ConcreteIteratorDesc 即可。

测试结果

车位No.1乘客:琦玉
琦玉 来不及解释了,快上车!
纳兹 来不及解释了,快上车!
悟空 来不及解释了,快上车!
一护 来不及解释了,快上车!
鸣人 来不及解释了,快上车!
路飞 来不及解释了,快上车!

总结

迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明的访问集合内部的数据。

(0)

相关推荐

  • 软件设计模式修炼 -- 迭代器模式

    迭代器模式是一种使用频率非常高的设计模式,迭代器用于对一个聚合对象进行遍历.通过引入迭代器可以将数据的遍历功能从聚合对象中分离出来,聚合对象只负责存储数据,聚合对象只负责存储数据,而遍历数据由迭代器来 ...

  • PHP的SPL扩展库(四)函数

    PHP的SPL扩展库(四)函数 今天我们继续来学习 SPL 中的内容,这篇文章的内容是比较简单的关于 SPL 中所提供的一系列函数相关的内容.其实在之前的不少文章中我们都已经接触过一些 SPL 中提供 ...

  • 一些JavaSE学习过程中的思路整理(四)(主观性强,持续更新中...)

    多线程编程:资源类&任务&运行机制的解耦合 一下是<Java核心技术卷一>中的一个样例,用多线程并发模拟银行账户的转账过程,该样例还未使用上锁机制,是一个有问题的样例,但是 ...

  • PHP设计模式—迭代器模式

    定义: 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 结构: Iterator:迭代器接口,用于定义得到开始对象.得到下一个对象.判断是否到 ...

  • Python生成器和迭代器有什么用?

    当我们学习Python的时候,会遇到很多专业的术语及工具,而对于这些很多人并不是很了解,比如说生成器和迭代器,Python的生成器和迭代器有什么区别?这是很多人都比较疑惑的问题,我们来看看吧. 迭代器 ...

  • 大话设计模式笔记(十三)の状态模式

    举个栗子 问题描述 上班的日子,上午状态好,中午想睡觉,下午渐恢复,加班苦煎熬.根据时间的不同体现不同的工作状态. 简单实现 Work /** * 工作类 * Created by callmeDev ...

  • 大话设计模式笔记(七)の原型模式

    举个栗子 问题描述 要求有一个简历类,必须要有姓名,可以设置性别和年龄,可以设置工作经历,最终需要三份简历. 简单实现 简历类 /** * 简历类 * Created by callmeDevil o ...

  • 大话设计模式笔记(六)の工厂方法模式

    栗子回顾 简单工厂模式: https://www.cnblogs.com/call-me-devil/p/10926633.html 运算类使用工厂方法模式实现 UML图 代码实现 工厂接口 /** ...

  • 大话设计模式笔记(五)の代理模式

    举个栗子 故事是这样的... 一个小伙子喜欢上了隔壁班的一个妹子,但是又不认识,也害羞不好意思主动去说话,于是拜托了同样在这个班的一个朋友去传递自己想要送的礼物... 代码实现 该模式就不上什么简单实 ...

  • 大话设计模式笔记(二)の策略模式

    举个栗子 问题描述 商场收银软件,营业员根据客户所购买的商品单价和数量,向客户收费. 简单实现 /** * 普通实现 * Created by callmeDevil on 2019/6/1. */ ...

  • 大话设计模式笔记(一)の简单工厂模式

    概要 一个好的程序猿/媛敲出来的代码应该是可维护.可复用.可扩展的,也就是具有较好的灵活性. 为了达到以上目的,在还没敲代码之前,需要事先考虑通过何种方式能够使自己的程序的耦合度降低,最基本的便是面向 ...

  • 深入学习《大话设计模式》 简单工厂模式

    简单工厂模式 定义:封装改变,既然要封装改变,自然也就要找到需要更改的代码,然后将需要更改的代码用类来封装,这样的思路就是我们简单工厂模式的实现方式了 下面我们通过一则小故事来简述一下我们在项目中为什 ...

  • 大话设计模式笔记(十八)の单例模式

    单例模式 定义 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象.一个最好的办法就是,让类自身负责保存它的唯一实例.这 ...

  • 大话设计模式笔记(四)の装饰模式

    举个栗子 问题描述 可以给人搭配嘻哈服或白领装的程序. 简单实现 代码 /** * 人类 * Created by callmeDevil on 2019/6/23. */ public class ...