浅谈设计模式 - 迭代器模式(十一)

简介: 浅谈设计模式 - 迭代器模式(十一)

前言


迭代器模式通常只需要知道该模式的实现原理和了解结构图即可,在设计模式当中自己实现的情况几乎是没有的,所以这个模式简单的过一遍。


什么是迭代器模式


定义:提供顺序的方法访问一个聚合对象的各个元素,同时又不会暴露内部的功能

迭代器模式通过接管遍历的细节,让提供方不必关心迭代的具体细节,只需要提供对应的聚合对象即可。


迭代器模式和增强的FOR循环:

Jdk1.5之后,将泛型和增强for循环加入到语言体系,可以直接对于集合的内容进行for循环查看,其实本质上还是调用了iterator方法,而java通过语法糖的形式为我们进行的遍历的隐藏。


迭代器模式结构图


迭代器模式的结构图如下:


网络异常,图片无法展示
|


Aggregate:聚合对象的共同接口,定义了具备遍历功能的聚合对象,通过定义创建迭代器的接口来建立与迭代器的组合
ConcreateAggregate:具体的迭代器实现对象,通过接口方法返回具体的迭代器实现
Iterator:迭代器接口,定义迭代器的统一规范,所以派生类都需要强制按照接口标准执行迭代器的实现。保证迭代器具备相似的行为。
ConcreteIterator:具体的迭代器实现,内部聚合对象的同时,可以扩展迭代器的遍历方式,比如ListIterator。
复制代码


迭代器模式特点


  • 迭代器将遍历的细节进行了封装,聚合对象不需要在关心客户端如何操作内部的变量,而是通过委托给迭代器的形式交由迭代器去完成具体的遍历细节。
  • 迭代器可以在不暴露内部结构的同时让外界可以访问到内部的聚合对象,所以即使是完全不同的对象也可以统一对待和处理。
  • 迭代器是一种职责的转移,将遍历的工作从原本的聚合对象中进行独立,能在不改动数据结构的同时改变数据的操作方式


迭代器的注意事项:


  1. 需要注意迭代器存在内部的迭代器外部的迭代器,内部的迭代器供对象本身使用不对外开放,外部的迭代器通过方法返回给调用方使用。
  2. 每个责任对应一个区域,超过区域意味多了一个责任,遍历和数据操作实际上是两个操作,应该区分对待。
  3. 注意迭代器是如何体现单一职责的原则,他剥离了遍历对象的功能,将其封装到一个迭代器内部进行使用。
  4. 好的迭代器应当具备“快速失败机制”,目的是为了防止操作内部元素的指针越界,同时及时通知客户端遍历异常。
  5. 如果想让方法不支持某些功能,最好使用异常机制提醒客户端我不支持某些操作。


案例



光有理论还是不够的,这里配合代码讲解迭代器是如何实现解耦聚合对象的遍历的。


模拟场景:


由于迭代器在实际工作中使用概率 几乎为0,这里设置的场景比较简单

我们使用window最常见的文件系统来作为案例,我们通常进入不同的磁盘,首先就是对该磁盘下面的第一级目录进行遍历,同时我们根据遍历方式的不同,可以将页面展示为分组,按照时间排序,显示不同的详略信息.....这些功能的本质都是遍历,只不过遍历的形式不同,为了实现对于菜单的不同形式遍历,我们通过定义不同迭代器来完成这一个目标。


接着,我们会发现迭代的种类丰富还不够,我们还需要迭代其他的内容,比如任务管理器需要迭代不同的进程,同样也包含了排序的或者隐藏部分进程等等一系列的功能,所以需要让不同的对象可以支撑相似的迭代操作,并且可以自由的替换迭代的方式,当然这部分功能不会放入案例部分,案例部分为简单的迭代器实现。


具体实现


在进行具体的编码之前,先检查一下需要的基本构建类:


Travelsable:定义对象具备迭代的功能接口。
MissionBoard:任务栏,贮存基本的任务信息,提供迭代器供外部展示。
TaskItemlIterator:任务迭代器,用于任务的迭代操作
ConcreteCatalogIterator:目录迭代器的实现具体子类,定义了不同的迭代种类。
TaskItem 任务项,定义一个任务的内容
Computer 电脑,只需要管理任务栏和文件管理器即可。
FileManager 文件管理器,负责管理文件夹的内容
FileIterator 文件迭代器,管理文件夹的迭代操作
FileItem 文件项
复制代码


下面直接按照结构图构建具体代码:


// 电脑,只需要管理任务栏和文件管理器即可。
public class Computer {
    private FileManager fileManager;
    private MissionBoard missionBoard;
    public Computer(FileManager fileManager, MissionBoard missionBoard) {
        this.fileManager = fileManager;
        this.missionBoard = missionBoard;
    }
    public void display(){
        Iterator fileManagerIterator = fileManager.createIterator();
        Iterator missionBoardIterator = missionBoard.createIterator();
        while (fileManagerIterator.hasNext()){
            Object next = fileManagerIterator.next();
            System.out.println(next);
        }
        while (missionBoardIterator.hasNext()){
            Object next = missionBoardIterator.next();
            System.out.println(next);
        }
    }
}
// 文件项
public class FileItem {
    private String fileName;
    private String editDate;
    private String ceateDate;
    private long size;
    // 省略部分内容
}
// 任务项
public class TaskItem {
    private String name;
    private int size;
    // 省略部分内容
}
// 迭代器规范接口
public interface Travelsable<E extends Object>{
    /**
     * 创建迭代器的方法
     * @return
     */
    Iterator<E> createIterator();
}
// 任务栏,管理任务项. 实现接口,支持迭代操作
public class MissionBoard implements Travelsable {
    private Stack<TaskItem> taskItems;
    public MissionBoard() {
        taskItems = new Stack<>();
        taskItems.push(new TaskItem("任务1", 10));
        taskItems.push(new TaskItem("任务2", 1230));
        taskItems.push(new TaskItem("任务3", 123));
        taskItems.push(new TaskItem("任务4", 414));
        taskItems.push(new TaskItem("任务5", 555));
    }
    @Override
    public Iterator createIterator() {
        return new TaskItemlIterator(taskItems);
    }
}
// 文件管理器,管理文件项,实现接口并且支持迭代操作
public class FileManager implements Travelsable{
    private FileItem[] fileItems;
    public FileManager() {
        this.fileItems = new FileItem[10];
        Random random = new Random(10000);
        for (int i = 0; i < fileItems.length; i++) {
            fileItems[i] = new FileItem("文件"+i, random.nextInt(2000));
        }
    }
    @Override
    public Iterator createIterator() {
        return new FileIterator(fileItems);
    }
}
//文件迭代器
public class FileIterator implements Iterator{
    private FileItem[] fileItems;
    private int index;
    public FileIterator(FileItem[] fileItems) {
        this.fileItems = fileItems;
        this.index = 0;
    }
    @Override
    public boolean hasNext() {
        return index++ < fileItems.length - 1;
    }
    @Override
    public Object next() {
        return fileItems[index];
    }
    @Override
    public void remove(Object ele) {
        throw new UnsupportedOperationException("数组不支持当前操作");
    }
}
// 任务迭代器
public class TaskItemlIterator implements Iterator{
    private Stack<TaskItem> taskItems;
    public TaskItemlIterator(Stack<TaskItem> taskItems) {
        this.taskItems = taskItems;
    }
    @Override
    public boolean hasNext() {
        if(taskItems.isEmpty()){
            return false;
        }
        TaskItem peek = taskItems.peek();
        return peek != null;
    }
    @Override
    public Object next() {
        return taskItems.pop();
    }
    @Override
    public void remove(Object ele) {
        taskItems.remove(ele);
    }
}
复制代码


以上就是迭代的大致实现案例代码,现代编程基本不会自己去设计迭代器,所以了解概念和知道样板代码即可。


总结:


迭代器在JAVA语言中基本已经实现到集合当中,当我们遍历集合的时候,其实就是在使用迭代器,迭代器通过封装遍历解耦了一堆对象的遍历和创建工作,将迭代的细节封装到一个黑盒当中,外部只需要调用接口就可以操作集合的数据。

相关文章
|
存储 JavaScript 前端开发
JS 数组操作的利器:splice() 和 slice() 方法详解
JS 数组操作的利器:splice() 和 slice() 方法详解
687 0
|
6月前
|
设计模式 数据采集 算法
【设计模式】【行为型模式】模板方法模式(Template Method)
一、入门 1.1、什么是模板方法模式? 模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个算法的框架,并允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
230 13
|
9月前
|
设计模式 Java Go
【再谈设计模式】状态模式~对象行为的状态驱动者
状态模式属于行为型设计模式。它将对象的行为封装在不同的状态类中,使得对象在不同的状态下表现出不同的行为。上下文(Context):这是一个包含状态对象的类,它定义了客户感兴趣的接口,并维护一个具体状态对象的引用。上下文将操作委托给当前的状态对象来处理。抽象状态(State):这是一个抽象类或者接口,它定义了一个特定状态下的行为接口。所有具体的状态类都实现这个接口。具体状态(Concrete State):这些是实现抽象状态接口的类,每个具体状态类实现了与该状态相关的行为。
337 18
|
10月前
|
设计模式 缓存 Java
「全网最细 + 实战源码案例」设计模式——代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,通过代理对象控制对目标对象的访问并添加额外功能。它分为静态代理和动态代理,后者包括JDK动态代理和CGLIB动态代理。JDK动态代理基于接口反射生成代理类,而CGLIB通过继承目标类生成子类。代理模式适用于延迟初始化、访问控制、远程服务、日志记录和缓存等场景,优点是职责分离、符合开闭原则和提高安全性,缺点是增加系统复杂性。
262 25
|
设计模式 Java
Java责任链模式
Java责任链模式
211 0
|
11月前
|
设计模式 C# C++
责任链模式(Chain of Responsibility Pattern)
责任链模式是一种行为型设计模式,允许多个对象按顺序处理请求,直到某个对象处理为止。适用于多个对象可能处理同一请求的场景,如请假审批流程。优点是灵活性高、降低耦合,但责任链过长可能影响性能。
|
设计模式 算法 Java
【十六】设计模式~~~行为型模式~~~策略模式(Java)
文章详细介绍了策略模式(Strategy Pattern),这是一种对象行为型模式,用于定义一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法独立于使用它的客户而变化,提高了系统的灵活性和可扩展性。通过电影院售票系统中不同类型用户的打折策略案例,展示了策略模式的动机、定义、结构、优点、缺点以及适用场景,并提供了Java代码实现和测试结果。
【十六】设计模式~~~行为型模式~~~策略模式(Java)
|
设计模式 Java 数据库连接
【设计模式——学习笔记】23种设计模式——外观模式Facade(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——外观模式Facade(原理讲解+应用场景介绍+案例介绍+Java代码实现)
310 0
|
程序员 图形学
ThreeJs模拟工厂生产过程五
这篇文章详细介绍了如何在Three.js中模拟工业生产过程的第五部分,重点在于添加并实现车间内人物的动态行走动画,使人能够在车间内来回移动,增加了场景的真实感。
205 0
|
JavaScript
Vue.js 中父组件调用子组件的方法
Vue.js 中父组件调用子组件的方法
1046 2