详解设计模式:迭代器模式

news2024/9/22 5:27:44

迭代器模式(Iterator Pattern)也被称为游标模式(Cursor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。是一种最简单也最常见的设计模式。

迭代器模式 可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。

本篇文章内容包括:关于迭代器模式、观察者模式 Demo、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)


文章目录

    • 一、关于迭代器模式
        • 1、关于迭代器模式
        • 2、关于迭代器模式的构成
        • 3、关于迭代器模式的XML
        • 4、关于迭代器模式的适用场景
        • 5、关于迭代器模式的优缺点
    • 二、观察者模式 Demo
        • 1、Demo 设计
        • 2、Demo 实现
        • 3、Demo 测试
    • 三、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)


一、关于迭代器模式

1、关于迭代器模式

迭代器模式(Iterator Pattern)也被称为游标模式(Cursor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。是一种最简单也最常见的设计模式。

迭代器模式 可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。

迭代器模式 提供一种方法顺序访问一个聚合(指一组对象的组合结构,如:Java中的集合、数组等)对象中各个元素,而又不需暴露该对象的内部表示。迭代器模式的本质:控制访问聚合对象中的元素。其设计意图:无须暴露聚合对象的内部实现,就能够访问到聚合对象中的各个元素。

2、关于迭代器模式的构成

迭代器模式主要包含以下 4 种角色:

  • 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。

  • 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。

  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。

  • 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

3、关于迭代器模式的XML

image-20221203180812127

4、关于迭代器模式的适用场景

  • 内容保密 : 访问 集合对象 的内容 , 无需暴露内部表示 ;
  • 统一接口 : 为遍历 不同的 集合结构 , 提供统一接口。

5、关于迭代器模式的优缺点

迭代器模式优点

  • 分离了集合对象的遍历行为;
  • 抽象出了迭代器负责集合对象的遍历 , 可以让外部的代码透明的访问集合内部的数据 ;

迭代器模式缺点

  • 类的个数成对增加;
  • 迭代器模式,将存储数据 , 遍历数据两个职责拆分 ;
  • 如果新添加一个 集合类 , 需要增加该 集合类 对应的 迭代器类 , 类的个数成对增加 , 在一定程度上 , 增加了系统复杂性 ;

二、观察者模式 Demo

1、Demo 设计

定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现。

Demo 类图如下:

在这里插入图片描述

2、Demo 实现

# Student 元素类

public class Student {

    private String name;

    private String number;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", number='" + number + '\'' +
                '}';
    }

    /**
     * 建造者类构造函数
     *
     * @param builder Builder
     */
    private Student(Builder builder) {
        name = builder.name;
        number = builder.number;
    }

    /**
     * 建造者类
     */
    public static final class Builder {

        private String name;

        private String number;

        public Builder() {
        }

        public Builder name(String val) {
            name = val;
            return this;
        }

        public Builder number(String val) {
            number = val;
            return this;
        }

        public Student build() {
            return new Student(this);
        }
    }
}

# StudentAggregate 抽象聚合(Aggregate)角色

public interface StudentAggregate {
    
    /**
     * 添加元素
     * @param student Student
     */
    void addStudent(Student student);

    /**
     * 删除元素
     * @param student Student
     */
    void removeStudent(Student student);

    /**
     * 获取迭代器对象
     * @return StudentIterator
     */
    StudentIterator getStudentIterator();
}

# StudentAggregateImpl 具体聚合(ConcreteAggregate)角色

import java.util.ArrayList;
import java.util.List;

public class StudentAggregateImpl implements StudentAggregate {

    /**
     * 学生列表
     */
    private final List<Student> list = new ArrayList<Student>();

    @Override
    public void addStudent(Student student) {
        this.list.add(student);
    }

    @Override
    public void removeStudent(Student student) {
        this.list.remove(student);
    }

    @Override
    public StudentIterator getStudentIterator() {
        return new StudentIteratorImpl(list);
    }
    
}

# StudentIterator 抽象迭代器(Iterator)角色

public interface StudentIterator {

    /**
     * 判断是否还有下一个元素
     * @return boolean
     */
    boolean hasNext();

    /**
     * 获取下一个元素
     * @return Student
     */
    Student next();
}

# StudentIteratorImpl 具体迭代器(Concretelterator)角色

import java.util.List;

public class StudentIteratorImpl implements StudentIterator {

    private final List<Student> list;
    private int position = 0;

    public StudentIteratorImpl(List<Student> list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        return position < list.size();
    }

    @Override
    public Student next() {
        Student currentStudent = list.get(position);
        position ++;
        return currentStudent;
    }
}

3、Demo 测试

public class Client {

    public static void main(String[] args) {
        
        // 抽象聚合类-StudentAggregate 具体聚合类-StudentAggregateImpl
        StudentAggregate studentAggregate = new StudentAggregateImpl();
        // 建造者模式构造元素
        studentAggregate.addStudent(new Student.Builder().name("小明").number("1001").build());
        studentAggregate.addStudent(new Student.Builder().name("小红").number("1002").build());
        // 通过 具体聚合类 获取 具体迭代器
        StudentIterator iterator = studentAggregate.getStudentIterator();
        
        // 迭代器遍历
        while (iterator.hasNext()){
            System.out.println(iterator.next().toString());
        }
    }
}

三、模版方法模式的应用(ArrayList/Iterator 中的迭代器模式)

Java 代码中关于 List 的迭代器使用:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorDemo {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("AA");
        list.add("BB");
        list.add("CC");
        
        // list.iterator() 方法返回的肯定是 Iterator 接口的子实现类对象
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

其中,List-抽象聚合类、ArrayList-具体的聚合类、Iterator-抽象迭代器、list.iterator() 返回的是实现了 Iterator 接口的具体迭代器对象。

# ArrayList 的源码对于迭代器部分的实现:

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
    
    public Iterator<E> iterator() {
        return new ArrayList.Itr();
    }
    
    
    private class Itr implements Iterator<E> {
      	// 下一个要返回元素的索引
        int cursor;       
      	// 上一个返回元素的索引
        int lastRet = -1; 
        int expectedModCount = modCount;

        Itr() {}
		
        //判断是否还有元素
        public boolean hasNext() {
            return cursor != size;
        }

        //获取下一个元素
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
        ...
    }
}

可以看到:在 iterator 方法中返回了一个实例化的 Iterator 对象。Itr 是一个内部类,它实现了 Iterator 接口并重写了其中的抽象方法。

// List 集成自 Collection
public interface List<E> extends Collection<E>

// Collection 继承自 Iterable
public interface Collection<E> extends Iterable<E>

Ps:当我们在使用 Java 开发的时候,想使用迭代器模式的话,只要让我们自己定义的容器类实现 java.util.Iterable 并实现其中的 iterator() 方法使其返回一个 java.util.Iterator 的实现类就可以了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/57916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML5期末大作业:美食网页主题网站设计与实现——HTML+CSS+JavaScript月饼美食食品企业网站html模板9页面

&#x1f468;‍&#x1f393;静态网站的编写主要是用HTML DIVCSS JS等来完成页面的排版设计&#x1f469;‍&#x1f393;,常用的网页设计软件有Dreamweaver、EditPlus、HBuilderX、VScode 、Webstorm、Animate等等&#xff0c;用的最多的还是DW&#xff0c;当然不同软件写出的…

[附源码]计算机毕业设计校园运动会管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Linux基本工具——vim

Linux编辑器vim什么是vimvim的三种常用模式vim的基本操作命令模式插入模式底行模式搭配vim环境sudo怎么才能让普通用户使用什么是vim vim是linux下一款功能强大&#xff0c;多模式的编辑器。 现阶段有13种模式。 这就是进入vim的方式。 vim的三种常用模式 命令模式 我们第一…

CentOS7 编译安装最新的Linux Kernel 6.0 rc3

哪个男孩不想手动编译一份自己的内核呢&#xff1f;安装编译环境 CentOS7安装必要的包 yum groupinstall "Development Tools" -y && yum install openssl-devel -y && yum install rpm-build redhat-rpm-config asciidoc hmaccalc perl-ExtUtils-…

Java核心技术卷Ⅰ-第四章对象和类

重点 1.使用预定义类 2.方法参数 3.对象构造 4.包 5.类设计技巧 1.使用预定义类 一个源文件只能有一个公共类&#xff0c;可以有任意数目的非公共类可以使用通配符调用Java编译器&#xff1a;javac Test*.java使用var声明局部变量就不用担心0、0L和0.0之间的区别&#xff0c;因…

找出链表中间结点的三种解法

初阶链表刷题注意&#xff01;&#xff01;&#xff01;学习的是解题的思维&#xff01; 找出链表的中间结点&#xff08;链接在末尾&#xff09; 解题思路 数组解法 由于链表不能通过下标访问对应的结点&#xff0c;所以我们将所有的结点存储在数组中&#xff0c;这样就可以通…

测试开发怎么学?

随着互联网行业的高速发展,快速高质量的产品版本迭代成为企业始终立于不败之地的迫切需求,而在短期迭代的快节奏中.传统测试工作面对更大压力,无法持续提供高效率高质量的人力支撑&#xff0c;所以越来越多的企业需要技术更为全面的测试开发工程师。 测试开发本质上属于测试,区…

【数据结构】二叉树链式结构的实现

&#x1f451;作者主页&#xff1a;进击的安度因 &#x1f3e0;学习社区&#xff1a;进击的安度因&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;数据结构 文章目录一、二叉树的链式存储二、二叉树链式结构的实现结构设计手动构建二叉树前序遍历中序遍历…

游戏思考26:游戏服务器压力测试文档(最近在忙这个,这个会更新频繁,12/03未完待续)

文章目录一、压力测试关注点二、计算最耗时的加载操作1&#xff09;从数据库读取数据&#xff0c;对加载的类型进一步划分各种类型&#xff0c;计算最耗时操作2&#xff09;查看CPU随着在线人数的变化所占百分比3&#xff09;查看内存变化4&#xff09;备注一、压力测试关注点 …

【C语言字符串】一道题检验你的字符串学习情况

作者&#xff1a;匿名者Unit 目录 一.字符串引言1.字符串基础二.洛谷P5734详解1.字符串相关库函数&#xff08;1&#xff09; strcpy函数 &#xff08;2&#xff09; strcat函数 &#xff08;3&#xff09;strstr函数 2.题目讲解一.字符串引言 1.字符串基础 字符串通常以\0作为…

008. 子集

1.题目链接&#xff1a; 78. 子集 2.解题思路&#xff1a; 2.1.题目要求&#xff1a; 给一个元素各不相同的数组 nums&#xff0c;返回各种可能的子集&#xff08;子集不能重复&#xff09; 比如&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],[…

做了8年前端,感谢那些优秀的后端,陪伴我工作,教会我成长

☆ 前段时间由于一时的头脑发热&#xff0c;写了一篇《做了8年前端&#xff0c;细说那些曾经让你浴霸不能的后端》的博客&#xff0c;虽然每个细节也都属实吧&#xff0c;但始终是一些负能量的东西&#xff0c;建议大家不要去看了&#xff0c;今年互联网情况已经这样了&#xf…

安卓APP源码和设计报告——体育馆预约系统

项目名称&#xff1a;体育馆体育场预约系统专业&#xff1a;班级&#xff1a;学号&#xff1a;姓名&#xff1a; 目 录 一、项目功能介绍3 二、项目运行环境3 1、开发环境3 2、运行环境3 3、是否需要联网3 三、项目配置文件及工程结构4 1、工程配置文件4 2、工程结构目…

磨金石教育摄影技能干货分享|上海随手拍——叶落满街,秋意未尽

步入十二月以来&#xff0c;气温也随之骤降&#xff0c;这时候才明显感到初冬已至。冬天的寒风就是最好的脱叶剂&#xff0c;走在街道上&#xff0c;抬眼望去两旁的树木多数已经稀疏。只有残留的绿意还在迎着微微的寒风摇动。 我最喜欢的是秋天&#xff0c;因为秋天的草木最有色…

基于keras与tensorflow手工实现ResNet50网络

前言 在文章 基于tensorflow的ResNet50V2网络识别动物&#xff0c;我们使用了keras已经提供的神经网络&#xff0c;完成了图像分类的。这个时候&#xff0c;小明同学就问了&#xff0c;那么我怎么自己去写一个神经网络来进行训练呢&#xff1f; 本文就基于tensorflow&#xff…

Redis原理篇——五种基本数据类型

一、Redis底层数据结构 1. SDS 获取字符串长度耗时&#xff1a; 由于Redis底层是C语言编写的&#xff0c;C语言中没有字符串这个概念&#xff0c;本质上都是字符数组&#xff0c;获取字符串长度就是遍历数组获取长度&#xff08;遍历到 \0结束标识结束 &#xff09;时间复杂度…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java高校毕业生信息采集系统05hj2

大四计算机专业的同学们即将面临大学4年的最后一次考验--毕业设计。通过完成毕业设计来对过去4年的大学学习生活做一个总结&#xff0c;也是检验我们学习成果的一种方式&#xff0c;毕业设计作品也是我们将来面试找工作的一个敲门砖。 选题前先看看自己掌握哪些技术点、擅长哪…

数据库常用的数据类型和约束条件

文章目录一. 数据库常用的数据类型1. 数字类型1.1 整数类型:INT(m)和BIGINT(m)1.2 浮点类型:DOUBLE(m,n)2. 字符类型2.1 定长字符:CHAR(n)2.2 变长字符:VARCHAR(n)2.3 变长字符:TEXT(n)3. 日期类型3.1 语法格式:3.2 注意事项二. 约束条件1.主键约束(PRIMARY KEY)1.1 注意事项1.…

[附源码]Python计算机毕业设计Django美发店会员管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Web压测工具http_load原理分析

01、前言 http_load是一款测试web服务器性能的开源工具&#xff0c;从下面的网址可以下载到最新版本的http_load&#xff1a; http://www.acme.com/software/http_load/ 这个软件一直在保持着更新&#xff08;不像webbench&#xff0c;已经是十年的老古董了。 webbench的源…