设计模式 -- 迭代器模式(Iterator Pattern)

news2024/11/26 18:30:46

1 问题引出

        编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院, 一个学院有多个系

传统方式实现 

 

  1. 将学院看做是学校的子类,系是学院的子类,这样实际上是站在组织大小来进行分层次的

  2. 实际上我们的要求是 :在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系, 因此这种方案,不能很好实现的遍历的操作

2 基本介绍

  1. 迭代器模式(Iterator Pattern)是常用的设计模式,属于行为型模式

  2. 如果我们的集合元素是用不同的方式实现的,有数组,还有 java 的集合类,或者还有其他方式,当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。

  3. 迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。

3 原理结构图

3.1 类图

3.2 说明

  1. Iterator : 迭代器接口,是系统提供,含义 hasNext, next, remove

  2. ConcreteIterator : 具体的迭代器类,管理迭代

  3. Aggregate :一个统一的聚合接口, 将客户端和具体聚合解耦

  4. ConcreteAggreage : 具体的聚合持有对象集合, 并提供一个方法,返回一个迭代器, 该迭代器可以正确遍历集合

  5. Client :客户端, 通过 Iterator 和 Aggregate 依赖子类

4 应用实例

4.1 类图

4.2 代码实现

Client

public class Client {
​
    public static void main(String[] args) {
        //  创建学院
        List<College> collegeList = new ArrayList<College>();
​
        ComputerCollege computerCollege = new ComputerCollege();
        InfoCollege infoCollege = new InfoCollege();
​
        collegeList.add(computerCollege);
        //  collegeList.add(infoCollege);
​
        OutPutImpl outPutImpl = new OutPutImpl(collegeList);
        outPutImpl.printCollege();
    }
​
}

College

public interface College {
​
    public String getName();
​
    //  增加系的方法
    public void addDepartment(String name, String desc);
​
    //  返回一个迭代器,遍历
    public Iterator createIterator();
}

ComputerCollege

public class ComputerCollege implements College {
​
    Department[] departments;
    int numOfDepartment = 0;//  保存当前数组的对象个数
​
    public ComputerCollege() {
        departments = new Department[5];
        addDepartment("Java 专业", " Java 专业 ");
        addDepartment("PHP 专业", " PHP 专业 ");
        addDepartment("大数据专业", " 大数据专业 ");
    }
​
    @Override
    public String getName() {
        return "计算机学院";
    }
​
    @Override
    public void addDepartment(String name, String desc) {
        Department department = new Department(name, desc);
        departments[numOfDepartment] = department;
        numOfDepartment += 1;
    }
​
    @Override
    public Iterator createIterator() {
        return new ComputerCollegeIterator(departments);
    }
}

ComputerCollegeIterator

public class ComputerCollegeIterator implements Iterator {
​
    //  这里我们需要 Department 是以怎样的方式存放=>数组
    Department[] departments;
    int position = 0; //  遍历的位置
​
    public ComputerCollegeIterator(Department[] departments) {
        this.departments = departments;
    }
​
    //  判断是否还有下一个元素@Override
    public boolean hasNext() {
        //  TODO Auto-generated method stub
        if (position >= departments.length || departments[position] == null) {
            return false;
        } else {
            return true;
        }
    }
​
    @Override
    public Object next() {
        Department department = departments[position];
        position += 1;
        return department;
    }
​
    //  删除的方法,默认空实现
    public void remove() {}
​
}

Department

// 系
public class Department {
​
    private String name;
    private String desc;
​
    public Department(String name, String desc) {
        super();
        this.name = name;
        this.desc = desc;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public String getDesc() {
        return desc;
    }
​
    public void setDesc(String desc) {
        this.desc = desc;
    }
​
}

OutPutImpl

public class OutPutImpl {
​
    //  学院集合 
    List<College> collegeList;
​
    public OutPutImpl(List<College> collegeList) {
        this.collegeList = collegeList;
    }
​
    //  遍历所有学院,然后调用 printDepartment 输出各个学院的系
    public void printCollege() {
        //  从 collegeList 取出所有学院, Java 中的 List 已经实现 Iterator 
        Iterator<College> iterator = collegeList.iterator();
​
        while (iterator.hasNext()) {
            //  取出一个学院
            College college = iterator.next();
            System.out.println("=== " + college.getName() + "=====");
            printDepartment(college.createIterator()); //  得到对应迭代器
        }
    }
​
    //  输出 学院输出 系
    public void printDepartment(Iterator iterator) {
        while (iterator.hasNext()) {
            Department d = (Department) iterator.next();
            System.out.println(d.getName());
        }
    }
}

5 优缺点

5.1 优点

  1. 统一的遍历接口:迭代器模式提供了一致的方法来访问不同的集合类型,简化了客户端代码。
  2. 解耦集合与遍历逻辑:由于集合的遍历逻辑被封装在迭代器中,集合类可以专注于存储和管理数据。客户端要遍历聚合的时候只能取到迭代器,而不会知道聚合的具体组成。
  3. 支持多种遍历方式:同一个集合可以支持多种不同的遍历方式,只需添加新的迭代器即可。
  4. 扩展性:增加新的聚合类或迭代器类很方便,符合“开闭原则”。

5.2 缺点

  1. 增加复杂度:每增加一个新的集合类型,就需要增加一个新的迭代器类,这可能会增加系统的类数量。每个聚合对象都要一个迭代器,会生成多个迭代器不好管理类.
  2. 实现成本:对于简单的遍历需求,实现迭代器模式可能会显得过于繁琐和不必要。

6 迭代器模式的应用

  1. Java和.Net:在这些编程环境中,迭代器模式被广泛使用。Java的Iterator接口和.Net中的相似功能都是迭代器模式的实现。
  2. 生成器(Generator):在支持生成器功能的语言中,如JavaScript,生成器可以被视为一种特殊的迭代器,用于控制函数的执行流程。
  3. 遍历不同数据结构:在需要遍历不同数据结构(如数组、树、图)时,迭代器模式提供了统一的解决方案。

7 总结

        迭代器模式是一种强大的设计模式,它使得遍历各种复杂的数据结构变得简单和统一。通过将遍历的逻辑封装在迭代器中,迭代器模式不仅提供了对数据访问的抽象,还允许灵活地添加新的遍历算法而不影响现有的代码。然而,迭代器模式的实现可能会增加系统的复杂性,因此在选择使用该模式时应该权衡其利弊后,再做抉择。

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

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

相关文章

CPU性能对比 Intel 海光 鲲鹏920 飞腾2500

横向对比一下x86和ARM芯片&#xff0c;以及不同方案权衡下的性能比较 CPU基本信息 海光 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #lscpu Architecture: x86_64 CPU…

ssm基于微信小程序的食堂线上预约点餐系统论文源码调试讲解

2系统相关技术 2.1 Java语言简介 Java是由SUN公司推出&#xff0c;该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称&#xff0c;也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具备了显著的优势和广阔的前景&…

优化SQL查询之了解SQL执行顺序

文章目录 优化SQL查询之了解SQL执行顺序举例的SQL语句SQL执行顺序 - 文字解释SQL执行顺序 - 图示SQL执行顺序 - 动画演示distinct 子句会在哪个位置除了6个主要的关键字&#xff0c;还有哪些关键字总结 优化SQL查询之了解SQL执行顺序 SQL 查询的执行过程并非是简单的按照语句的…

话费接口API对接流程是什么?又有哪些优势?

话费接口 API 对接流程 前期准备 找一家专业做话费充值的公司&#xff0c;联系其商务了解对接的具体情况&#xff0c;包括合作模式、话费价格、消耗及打款金额是否可以开票、对接时是否有技术配合等 开户与对接 确定合作后在话费充值平台进行开户&#xff0c;获取账户参数及…

14、Django Admin的“Action(动作)”中添加额外操作

如图红框增加操作 将以下代码添加到HeroAdmin类中 actions ["mark_immortal"] def mark_immortal(self, request, queryset):queryset.update(is_immortalTrue) 修改后完整代码如下&#xff1a; admin.register(Hero) class HeroAdmin(admin.ModelAdmin):list_di…

c++返回一个pair类型

前言 Under the new standard we can list initialize the return value. 代码测试 #include<iostream> #include<string> #include<vector>std::pair<std::string, int> process(std::vector<std::string>& v) {if (!v.empty()){return …

无用但有趣的R包之教你怎么科学地用R语言摸鱼

如果你觉得R只是用来科研的工具&#xff0c;那就太辜负广大开发者的良苦用心了。今天给大家介绍几个useless但fun的的R包&#xff0c;为大家工作学习之余提供一点微不足道的小乐趣。 All work and no play makes jack a dull boy. 话不多说&#xff0c;游戏开始。 1.Fun包&a…

Nginx: 进程结构和信号量管理

进程结构 需要首先关注多进程和多线程的一个区别Nginx采用的是一种多进程&#xff0c;这样一种进程结构, 为何不采用多线程这样一种进程结构Nginx 设计之初就是为了高可能性和高可靠性而设计的Nginx 通常是运行在边缘节点上&#xff0c;通常是用来接受用户的第一个请求的时候&…

第三届人工智能与智能信息处理国际学术会议(AIIIP 2024)

目录 大会介绍 基本信息 合作单位 主讲嘉宾 会议组委 征文主题 ​编辑 参会方式 会议日程 中国-天津 | 2024年10月25-27日 | 会议官网&#xff1a;www.aiiip.net 大会介绍 第三届人工智能与智能信息处理国际学术会议&#xff08;AIIIP 2024&#xff09;将…

如何通过PLM系统提升企业研发效率与市场竞争力?

在当今快速变化的商业环境中&#xff0c;企业的研发能力和市场响应速度成为了决定其竞争力的关键因素。PLM系统作为一种集成了产品设计、开发、制造、销售、服务及最终报废等全生命周期信息的集成化管理平台&#xff0c;正逐渐成为企业提升研发效率、加速产品创新、优化资源配置…

Java后端面试题(微服务相关)(day12)

目录 分布式与微服务区别&#xff1f;什么是CAP原则&#xff1f;Spring Cloud Alibaba 组件有哪些&#xff1f;Nacos配置中心动态刷新原理目前主流的负载方案有哪些&#xff1f;Nginx作为服务端负载均衡器&#xff0c;常见的负载均衡策略有哪些&#xff1f;Spring Ribbon相关Sp…

中秋佳节,好物相伴 —— 精选五款数码好物推荐

中秋佳节&#xff0c;不仅是家人团聚的时刻&#xff0c;也是享受科技与生活的完美结合的好时机。在这个充满温情的节日里&#xff0c;我们为您精心挑选了五款数码好物&#xff0c;其中包括备受好评的南卡Runner Pro5骨传导耳机&#xff0c;以及其他四款各具特色的数码产品&…

中国电子学会Python3级等级考试202403客观题解析2

11、单选题 关于语句 fopen(r"c:\计算.txt",w)&#xff0c;下列描述不正确的是&#xff1f;&#xff08; &#xff09; A f 是变量 B w以写方式打开文件 C 如果文件“计算.txt”不存在&#xff0c;不会报错 D 如果文件“计算.txt”内原来有内容&#xff0c;将不…

数据库透明加密的定义与原理

数据库透明加密(TDE)是一种先进的加密技术&#xff0c;主要用于保护存储在数据库中的敏感数据&#xff0c;防止未经授权的访问和数据泄露。以下是对数据库透明加密的详细解析&#xff1a; 一、定义与原理 定义&#xff1a;数据库透明加密是一种在数据库管理系统(DBMS)中集成加密…

软考高级:系统架构设计师——软件架构设计 Chapter 笔记

软考高级&#xff1a;系统架构设计师——软件架构设计 1 软件架构设计—基本概念架构所处的位置架构发展历程架构的“41”视图例题 架构描述语言&#xff08;ADL&#xff09;例题 2软件架构设计—架构风格数据流风格调用/返回 风格独立构件风格虚拟机风格仓库风格&#xff08;以…

Codeforces Round 970 (Div. 3) (个人题解)(未补完)

前言&#xff1a; 昨天晚上的比赛&#xff0c;可惜E题太笨了没想到如何解决&#xff0c;不过好在看到F过的多直接跳过去写F了&#xff0c;能过个5个也还不错了&#xff0c;而且一个罚时也没吃。之后的题我还是会再能补的时候补完的噢&#xff01; 正文&#xff1a; 链接&…

ELK(Elasticsearch、Logstash、Kibana) 分布式日志搭建详细过程

ELK是三款软件的简称&#xff0c;分别是Elasticsearch、 Logstash、Kibana组成 本文中描述了ELK日志平台的详细搭建过程&#xff0c;不对工具用途做描述。 一、准备 安装包 所需安装包及官网下载地址&#xff1a; elasticsearch-8.14.3-linux-x86_64.tar.gz (https://www…

2024 【Delphi 12】苹果ios开发环境配置(五星保姆级)

目录 一、创建证书 1. 创建证书签名请求&#xff1a;&#xff08;在苹果电脑上操作&#xff09;&#xff1a; .certSigningRequest 文件 2. 创建证书&#xff1a;在苹果的 开发者网站 上操作 重复以上步骤并下载对应的证书文件如下&#xff1a; 3. 创建标识符&#xff08;…

引爆关注!LLM大模型开源项目突破34.4千星,热度飙升!

其实这个Repo在外网知名度很高&#xff0c;但咱这似乎没看到咋推 随着近两年大型语言模型的发展&#xff0c;LLM在生活中发挥着愈发重要的作用&#xff0c;通过改变我们与技术互动的方式&#xff0c;为医疗、金融和教育等各领域带来变革性的变化&#xff0c;之前AI周刊中也说了…

开放式耳机怎么戴?开放式耳机比入耳式耳机舒适吗?

开放式耳机佩戴教程如下&#xff1a; 选择合适的耳挂或支架&#xff1a;开放式耳机通常有耳挂式或头梁式等设计。如果是耳挂式&#xff0c;确保耳挂的大小和形状适合您的耳朵&#xff0c;能够稳固地挂在耳朵上&#xff1b;如果是头梁式&#xff0c;调整头梁的长度&#xff0c;使…