【行为型模型】迭代器模式

一、迭代器模式概述

        迭代器模式定义提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。把游走的任务放在送代器上,而不是聚合上。这样简化了聚含的接口和实现,也让责任各得其所。(对象行为型)

  • 迭代器模式的优缺点
    • 优点
      • 1.访问一个聚合对象的内容而无须暴露它的内部表示;
      • 2.遍历任务交由迭代器完成,这简化了聚合类;
      • 3.它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历;
      • 4.增加新的聚合类和迭代器类都很方便,无须修改原有代码;
      • 5.封装性良好,为遍历不同的聚合结构提供一个统一的接口;
    • 缺点
      • 增加了类的个数,这在一定程度上增加了系统的复杂性。

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

二、代码实现

        迭代器模式主要包含四个角色:

  • 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
  • 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
  • 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
        2.1 抽象聚合(MenuItem)
package iterator.Menu;
//抽象聚合角色
public class MenuItem {// 名称String name;// 描述String description;// 是否为素食boolean vegetarian;// 价格double price;public MenuItem(String name,String description,boolean vegetarian,double price) {this.name = name;this.description = description;this.vegetarian = vegetarian;this.price = price;}public String getName() {return name;}public String getDescription() {return description;}public double getPrice() {return price;}public boolean isVegetarian() {return vegetarian;}
}
        2.2 具体聚合(DinnerMenu)
package iterator.Menu;
//菜单类
public class DinnerMenu {// 菜单总数private final static int MAX_NUMBER_OF_ITEMS = 4;private MenuItem[] menuItems;// 菜单量private int numberOfItems = 0;// 初始化数组,添加菜单内容public DinnerMenu() {menuItems = new MenuItem[MAX_NUMBER_OF_ITEMS];addItem("pancake1", "good1", true, 10.5);addItem("pancake2", "good2", false, 11.5);addItem("pancake3", "good3", true, 12.5);addItem("pancake4", "good4", false, 13.5);}// 创建一个添加菜单方法public void addItem(String name, String description, boolean vegetarian, double prive) {MenuItem menuItem = new MenuItem(name, description, vegetarian, prive);if (numberOfItems >= MAX_NUMBER_OF_ITEMS) {throw new RuntimeException("超过最大数量");} else {//菜单没满可以继续添加menuItems[numberOfItems] = menuItem;numberOfItems++;}}// 使用迭代器遍历菜单public Iterator createIterator() {return new DinnerMenuIterator(this.menuItems);}//..其他方法
}
        2.3 抽象迭代器
package iterator.Menu;
//抽象迭代器
public interface Iterator {// hasNext()方法返回一个布尔值,让我们知道是否还有更多的元素boolean hasNext();// next()方法返回下一个元素Object next();
}
        2.4 具体迭代器(DinnerMenuIterator)
package iterator.Menu;
//具体迭代器,餐厅菜单
public class DinnerMenuIterator implements Iterator {MenuItem[] items;// iteratorIndex记录当前数组遍历的位置int iteratorIndex = 0;;// 构造器需要被传入一个菜单项的数组当做参数public DinnerMenuIterator(MenuItem[] items) {this.items = items;}// next()方法返回数组内的下一项,并递增其位置public Object next() {MenuItem menuItem = items[iteratorIndex];iteratorIndex = iteratorIndex + 1;return menuItem;}// hasNext()方法会检查我们是否已经取得数组内所有的元素。// 如果还有元素待遍历,则返回truepublic boolean hasNext() {if (iteratorIndex >= items.length || items[iteratorIndex] == null) {return false;} else {return true;}}
}
        2.5 服务员(Waitress)
package iterator.Menu;
//服务员
public class Waitress {PancakeHouseMenu pancakeHouseMenu;DinnerMenu dinnerMenu;// 在构造器中,女招待照顾两个菜单public Waitress(PancakeHouseMenu pancakeHouseMenu, DinnerMenu dinnerMenu) {this.pancakeHouseMenu = pancakeHouseMenu;this.dinnerMenu = dinnerMenu;}public void printMenu() {// 这个printMenu()方法为每一个菜单各自创建一个迭代器Iterator pancakeIterator = pancakeHouseMenu.createIterator();Iterator dinnerIterator = dinnerMenu.createIterator();// 然后调用重载的printMenu(),将迭代器传入printMenu(pancakeIterator);System.out.println("\nLunch");// 调用下面重载的方法printMenu(dinnerIterator);}// 这个重载的printMenu()方法,使用迭代器来遍历菜单项并打印出来// 使用迭代器(一次循环即可)来遍历菜单项并打印出来,只调用Iterator接口private void printMenu(Iterator iterator) {while (iterator.hasNext()) {MenuItem menuItem = (MenuItem) iterator.next();System.out.println(menuItem.getName() + " " +menuItem.getPrice() + " " + menuItem.getDescription());}}
}
        2.6 main方法实现迭代器(Test)
package iterator.Menu;public class Test {public static void main(String[] args) {// TODO Auto-generated method stubPancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();        DinnerMenu dineMenu = new DinnerMenu();/***两个菜单都实现一样的方法,但是并没有实现相同的接口,*女招待还是要依赖两个具体实现的菜单类*后面就要修改这里**/Waitress waitress = new Waitress(pancakeHouseMenu, dineMenu);waitress.printMenu();}}
        2.7 UML图

三、代码结构图

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

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

相关文章

数据结构之顺序表的实现(C语言版)

Hello, 大家好,我是一代,今天给大家带来有关顺序表的有关知识 所属专栏:数据结构 创作不易,望得到各位佬们的互三呦 一.前言 1.首先在讲顺序表之前我们先来了解什么是数据结构 数据结构是由“数据”和“结构”两词组合⽽来。 什…

C语言—深度剖析函数指针,函数指针数组

我们先来看一段代码 #include <stdio.h> void test() {printf("hehe\n"); } int main() {printf("%p\n", test);printf("%p\n", &test);return 0; }输出的是两个地址&#xff0c;这两个地址是 test 函数的地址。 那我们的函数的地址…

Electron 30.0.0 发布,升级 Node 和 V8 引擎

近日&#xff0c;Electron 30.0.0 正式发布&#xff01;你可以通过 npm install electronlatest 进行安装&#xff0c;或者从 Electron 的发布网站下载&#xff0c;继续阅读了解此版本的详细信息。 &#x1f525; 主要更新 Windows 上支持 ASAR 完整性融合。如果未正确配置&am…

软件测试——Postman Script脚本功能

Postman作为软件测试里一款非常流行的调试工具&#xff0c;给我们提供了一个执行JavaScript脚本的环境&#xff0c;所以我们可以使用js语言编写脚本来解决一些接口自动化的问题&#xff0c;比如接口依赖、接口断言等等。Postman有Pre-RequestScript和Tests两个编写js脚本的模块…

Jenkins 哲学 - 插件初始化安装失败

到Jenkins官网查找最新的LST版本 最后的版本号一定要带&#xff0c;指定下载具体的版本号 docker pull jenkins/jenkins:2.426.1 自定义挂载目录&#xff0c;修改权限 mkdir /jenkins/jenkins_homechmod 777 /data/jenkins

Ansible安装基本原理及操作(初识)

作者主页&#xff1a;点击&#xff01; Ansible专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月23日15点18分 Ansible 是一款功能强大且易于使用的IT自动化工具&#xff0c;可用于配置管理、应用程序部署和云端管理。它使用无代理模式&#xff08;agentles…

谈谈mysql中的各个关键字

1.为什么学习mysql mysql是当今最主流且开放源码的关系型数据库&#xff0c;开发者为瑞典 MySQL AB 公司。目前 MySQL 被广泛地应用在 Internet 上的中小型网站中。由于其体积小、速度快、总体拥有成本低&#xff0c;尤其是开放源码这一特点&#xff0c;许多中小型网站为了降低…

【C语言】每日一题,快速提升(10)!

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 题目&#xff1a;圣诞树 输入&#xff1a; 1输出&#xff1a; * * * * * **说明&#xff1a; 输入&#xff1a; 2输出&#xff1a; * * * * * * * …

C++:基础语法

一、命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c; 以避免命名冲突或名字污染&#xff0c;n…

【C++】一篇文章带你深入了解list

目录 一、list的介绍二、 标准库中的list类2.1 list的常见接口说明2.1.1 list对象的常见构造2.1.1.1 [无参构造函数](https://legacy.cplusplus.com/reference/list/list/list/)2.1.1.2 [有参构造函数(构造并初始化n个val)](https://legacy.cplusplus.com/reference/list/list/…

上位机图像处理和嵌入式模块部署(树莓派4b开机启动脚本)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 编写好程序之后&#xff0c;一般要求程序开机启动后就可以运行。所以这个时候&#xff0c;我们一般就会把程序流程放在开发板的启动脚本当中。如果…

开源大模型应该怎么选?

文章目录 前言为什么选择开源模型而不是商业模型?开源模型对比Llama 2Mixtral 8x7BZephyr 7BSOLAR 10.7BCode Llama 专用 Vs. 通用生产环境部署LLMs 的注意事项 前言 在过去的一年里&#xff0c;人工智能领域不断涌现出各种大语言模型(LLMs)&#xff0c;每个模型都在不断突破生…

SpringBoot之@Conditional衍生条件装配详解

文章目录 ☃️前言☃️简介☃️示例❄️❄️ConditionalOnProperty❄️❄️ConditionalOnClass❄️❄️ConditionalOnBean❄️❄️自定义条件 ☃️SpringBoot源码中使用☃️总结 欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博客…

pET-28a(+)是什么,怎么看?-实验操作系列-1

01 典型的pET-28a()质粒遗传图谱 02 元件解读 Origin复制子&#xff1a;ColE1/pMB1/pBR322/pUC ori——起始载体的复制&#xff1b;f1 ori——f1噬菌体复制子&#xff0c;显示正义链合成方向。The origin of replication&#xff0c;由复制起始位点和相关调控元件组成&#xf…

Midjourney-01 初试上手 注册使用并生成你的第一张AI图片 详细流程 提示词 过程截图 生成结果 付费文生图的天花板!

背景介绍 Midjourney是一款基于人工智能技术的绘画软件&#xff0c;利用深度学习算法来辅助用户进行绘画创作。这款软件能够通过用户输入的文本描述生成图像&#xff0c;支持多种生成方式&#xff0c;包括文字生成图片、图片生成图片和混合图片生成图片。 图像生成方式&#…

【智能算法】蜉蝣算法(MA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2020年&#xff0c;K Zervoudakis等人受到自然界蜉蝣交配繁殖行为启发&#xff0c;提出了蜉蝣算法&#xff08;Mayfly Algorithm, MA&#xff09;。 2.算法原理 2.1算法思想 MA灵感来自蜉蝣交配…

如何高效的压缩GIF图片?一键搞定GIF动图压缩 就是这么简单

一&#xff0c;引言 压缩GIF动图是一个常见的需求&#xff0c;无论是在社交媒体上分享动态表情&#xff0c;还是在网页设计中添加动态元素&#xff0c;GIF动图都扮演着重要的角色。然而&#xff0c;过大的GIF文件大小可能会导致加载速度慢&#xff0c;影响用户体验。因此&…

代码随想录学习Day 30

860.柠檬水找零 题目链接 讲解链接 思路&#xff1a;需要找零的情况是顾客支付10元或20元&#xff0c;尤其是支付20元时需要考虑找零的方式&#xff0c;此时可以选择找零3张5元或者一张10元一张5元&#xff0c;按照贪心算法的思路来看&#xff1a; 局部最优&#xff1a;在找…

常见的数据抽取工具对比

1.什么是ETL? ETL&#xff0c;是英文Extract-Transform-Load的缩写&#xff0c;用来描述将数据从来源端经过抽取&#xff08;extract&#xff09;、转换&#xff08;transform&#xff09;、加载&#xff08;load&#xff09;至目的端的过程&#xff0c;是数据仓库的生命线。 …

中红医疗:纷享销客CRM系统如何助力​数字化“狂飙”

纷享销客深耕 CRM 多年&#xff0c;可以顺畅打通 CRM 和 ERP 系统客户资源池&#xff0c;将金蝶苍穹平台的物料、产品基础主数据作为档案同步到纷享销客&#xff0c;以便商务维护好产品及库存。 纷享销客通过成熟的集成方案提高系统耦合性&#xff0c;让销售实时获得新产品及营…