当前位置: 首页 > news >正文

设计模式之九:迭代器与组合模式

有许多方法可以把对象堆起来成为一个集合(Collection),比如放入数组、堆栈或散列表中。若用户直接从这些数据结构中取出对象,则需要知道具体是存在什么数据结构中(如栈就用peek,数组[])。迭代器能够让客户遍历你的对象而又无法窥视你存储对象的方式。

对象村餐厅和煎饼屋合并了,它们有着不同的菜单列表,但菜单项基础都是一样的。

class MenuItem
{
private:string name;string description;bool vegetarian;double price;public:MenuItem(string name, string description, bool vegetarian, double price){this->name = name;this->description = description;this->vegetarian = vegetarian;this->price = price;}string getName(){return name;}string getDescription(){return description;}bool isVegetarian(){return vegetarian;}double getpPrice(){return price;}
};

下面就写Java代码了,改成C++一时半会还是做不过来。

public class PancakeHouseMenu
{ArrayList menuItems;public PancakeHouseMenu(){menuItems = new ArrayList();addItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99);}public void addItem(String name, String description, boolean vegetarian, double price){MenuItem menuItem = new MenuItem(name, description, vegetarian, price);menuItems.add(menuItem);}public ArrayList getMenuItems(){return menuItems;}
};/ ********************************************************/
public class DinerMenu
{static final int MAX_ITEMS = 6;int numberOfItems = 0;MenuItem[] menuItems;public DinerMenu(){menuItems = new MenuItem[MAX_ITEMS];addItem("Vegetarian BLT", "Fakin Bacon", true, 2.99);}public void addItem(String name, String description, boolean vegetarian, double price){MenuItem menuItem = new MenuItem(name, description, vegetarian, price);if (numberOfItems >= MAX_ITEMS){System.err.println("Sorry, menu is full! Can't add item to menu");}else{menuItems[numberOfItems++] = menuItem;}}public MenuItem[] getMenuItems(){return menuItems;}
};

这两种不同的菜单表现方式,会使得女招待需要知道菜单的实现细节,才能对菜单进行遍历。

PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
ArrayList breakfastItems = pancakeHouseMenu.getMenuItems();for breakfastItems.size()
MenuItem menuItem = (MenuItem)breakfastItems.get(i);/ ******************************************************************* /
DinerMenu dinerMenu = new DinerMenu();
MenuItem[] lunchItems = DinerMenu.getMenuItems();for lunchItems.size()
MenuItem menuItem = lunchItems[i];

如果还有第三家餐厅以不同的实现出现,我们就需要有三个循环。

因此,我们需要创建一个对象(迭代器),封装“遍历集合内的每个对象的过程”。

Iterator iter = breakfastItems.createIterator();while (iter.hasNext())
{MenuItem menuItem = (MenuItem)iter.next();
}

 当我们拥有迭代器接口后,我们就可以为各种对象集合实现迭代器

public interface Iterator
{boolean hasNext();Object next();
};public class DinerMenuIterator implements Iterator
{MenuItem[] items;int position = 0;public DinerMenuIterator(MenuItem[] items){this.items = items;}public Object next(){MenuItem menuItem = items[position++];return menuItem;}public boolean hasNext(){if (position >= items.length || items[position] == null) return false;else return true;}
};

有了DinerMenuIterator后就可以改造DinerMenu和PancakeHouseMenu。

public class DinerMenu
{static final int MAX_ITEMS = 6;int numberOfItems = 0;MenuItem[] menuItems;// public DinerMenu()// addItem()// 删除getMenuItems()public Iterator createIterator(){// 返回迭代器接口。客户不需要知道餐厅菜单如何维护菜单项return new DinerMenuIterator(menuItems);}
};
public class Waitress {PancakeHouseMenu pancakeHouseMenu;DinerMenu dinerMenu;public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {this.pancakeHouseMenu = pancakeHouseMenu;this.dinerMenu = dinerMenu;}public void printMenu() {Iterator pancakeIterator = pancakeHouseMenu.createIterator();Iterator dinerIterator = dinerMenu.createIterator();System.out.println("MENU\n----\nBREAKFAST");printMenu(pancakeIterator);System.out.println("\nLUNCH");printMenu(dinerIterator);}private void printMenu(Iterator iterator) {while (iterator.hasNext()) {MenuItem menuItem = iterator.next();System.out.print(menuItem.getName() + ", ");System.out.print(menuItem.getPrice() + " -- ");System.out.println(menuItem.getDescription());}}
}

现在可以进一步对waitress进行优化,因为她还捆绑与两个具体的菜单类。但在优化之前,我们先看下目前的设计。

 除了使用自己构建的迭代器接口外,还可以直接使用java.util的迭代器接口,同时ArrayList也有一个返回迭代器的方法。

 

// 煎饼屋的代码public Iterator createIterator()
{return menuItems.iterator();
}// 餐厅的代码public class DinerMenuIterator implements Iterator {MenuItem[] list;int position = 0;public DinerMenuIterator(MenuItem[] list) {this.list = list;}public MenuItem next() {MenuItem menuItem = list[position];position = position + 1;return menuItem;}public boolean hasNext() {if (position >= list.length || list[position] == null) {return false;} else {return true;}}public void remove() {if (position <= 0) {throw new IllegalStateException("You can't remove an item until you've done at least one next()");}if (list[position-1] != null) {for (int i = position-1; i < (list.length-1); i++) {list[i] = list[i+1];}list[list.length-1] = null;}}}

最后我们再给菜单一个共同的接口,然后修改下女招待。

public interface Menu
{public Iterator createIterator();
}public class Waitress {Menu pancakeHouseMenu;Menu dinerMenu;public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {this.pancakeHouseMenu = pancakeHouseMenu;this.dinerMenu = dinerMenu;}public void printMenu() {Iterator<MenuItem> pancakeIterator = pancakeHouseMenu.createIterator();Iterator<MenuItem> dinerIterator = dinerMenu.createIterator();System.out.println("MENU\n----\nBREAKFAST");printMenu(pancakeIterator);System.out.println("\nLUNCH");printMenu(dinerIterator);}private void printMenu(Iterator iterator) {while (iterator.hasNext()) {MenuItem menuItem = (MenuItem)iterator.next();System.out.print(menuItem.getName() + ", ");System.out.print(menuItem.getPrice() + " -- ");System.out.println(menuItem.getDescription());}}}

 

相关文章:

设计模式之九:迭代器与组合模式

有许多方法可以把对象堆起来成为一个集合&#xff08;Collection&#xff09;&#xff0c;比如放入数组、堆栈或散列表中。若用户直接从这些数据结构中取出对象&#xff0c;则需要知道具体是存在什么数据结构中&#xff08;如栈就用peek&#xff0c;数组[]&#xff09;。迭代器…...

官方推荐:6种Pandas读取Excel的方法

Pandas提供了多种读取Excel文件的方法&#xff0c;以下是官方推荐的6种方法&#xff1a; 1. 使用pd.read_excel()函数 这是最常用的方法&#xff0c;可以读取Excel文件&#xff0c;并将其转换为Pandas数据框。可以指定工作表名和列名的行号。 df pd.read_excel(data.xlsx, …...

Redis与Mysql区别

一、关系型数据库 mysql&#xff0c;pgsql,oracle ,sqlserver 支持连表关联查询&#xff08;会有一些特定的语法特特性&#xff09; 二、非关系型数据库 redis,mongodb,memcache &#xff08;key-value&#xff09; 三、关系型数据库与非关系型数据库的区别&#xff1a; 1&am…...

Black-Box Tuning for Language-Model-as-a-Service

本文是LLM系列的文章&#xff0c;针对《Black-Box Tuning for Language-Model-as-a-Service》的翻译。 语义模型即服务的黑盒调整 摘要1 引言2 背景3 方法4 实验5 讨论与未来工作 摘要 GPT-3等超大的预训练语言模型&#xff08;PTM&#xff09;通常作为服务发布。它允许用户设…...

通用的ARM64架构镜像

#此链接包含x86架构和ARM架构的pytorch镜像&#xff0c;镜像里面已下载好各种第三方库&#xff0c;GPU版本的pytorch可用。缺点&#xff1a;镜像有点大 测试环境&#xff1a;操作系统麒麟银河V10&#xff0c;ARM64处理器&#xff08;cpu&#xff09;&#xff0c;显卡为T4显卡 …...

git大文件推送报错

报错信息 不多掰扯&#xff0c;直接上报错信息和截图 Delta compression using up to 8 threadsRPC failde; HTTP 413 curl 22 The requested URL returned error: 413 Request Entity Too Large从以上的报错信息不难看出推送仓库的时候&#xff0c;请求体过大&#xff0c;为…...

RDMA性能优化经验浅谈

一、RDMA概述 首先我们介绍一下RDMA的一些核心概念&#xff0c;当然了&#xff0c;我并不打算写他的API以及调用方式&#xff0c;我们更多关注这些基础概念背后的硬件执行方式和原理&#xff0c;对于这些原理的理解是能够写出高性能RDMA程序的关键。 Memory Region RDMA的网…...

day 44 | ● 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费

309.最佳买卖股票时机含冷冻期 此外&#xff0c;在返回的时候&#xff0c;由于状态234都是卖出的状态&#xff0c;所以要比较其最大值进行返回。 func maxProfit(prices []int) int {dp : make([][]int, len(prices))dp[0] make([]int, 4)dp[0][0] -prices[0]for i : 1; i &…...

电子科大软件系统架构设计——系统分析与设计概述(含课堂作业、练习答案)

系统分析与设计概述 信息系统概述 what 信息系统是一种能够完成对业务数据进行采集、转换、加工、计算、分析、传输、维护等信息处理&#xff0c;并能就某个方面问题给用户提供信息服务的计算机应用系统。 组成 信息化基础设施&#xff08;计算机、计算机网络、服务器、系统…...

【SpringMVC】@RequestMapping注解(详解)

文章目录 前言1、RequestMapping注解的功能2、RequestMapping注解的位置3、RequestMapping注解的value属性4、RequestMapping注解的method属性1、对于处理指定请求方式的控制器方法&#xff0c;SpringMVC中提供了RequestMapping的派生注解2、常用的请求方式有get&#xff0c;po…...

8.(Python数模)马尔科夫链预测

Python实现马尔科夫链预测 马尔科夫链原理 马尔科夫链是一种进行预测的方法&#xff0c;常用于系统未来时刻情况只和现在有关&#xff0c;而与过去无关。 用下面这个例子来讲述马尔科夫链。 如何预测下一时刻计算机发生故障的概率&#xff1f; 当前状态只存在0&#xff08;故…...

什么是浏览器缓存(browser caching)?如何使用HTTP头来控制缓存?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 浏览器缓存和HTTP头控制缓存⭐ HTTP头控制缓存1. Cache-Control2. Expires3. Last-Modified 和 If-Modified-Since4. ETag 和 If-None-Match ⭐ 缓存策略⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击…...

谁需要了解学习RPA?什么地方可以使用RPA?

RPA&#xff08;Robotic Process Automation&#xff09;是一种通过软件机器人自动化执行特定任务和流程的技术。以下是一些需要了解RPA的人群&#xff1a; 企业决策者&#xff1a;企业决策者需要了解RPA的潜在收益和风险&#xff0c;以及如何将其纳入企业的数字化转型战略中。…...

Qt各个版本下载及安装教程(离线和非离线安装)

Qt各个版本下载链接&#xff1a; Index of /archive/qthttps://download.qt.io/archive/qt/ 离线安装 &#xff0c;离线安装很无脑&#xff0c;下一步下一步就可以。 我离线下载 半个小时把2G的exe下载下来了...

使用爬虫代码获得深度学习目标检测或者语义分割中的图片。

问题描述&#xff1a;目标检测或者图像分割需要大量的数据&#xff0c;如果手动从网上找的话会比较慢&#xff0c;这时候&#xff0c;我们可以从网上爬虫下来&#xff0c;然后自己筛选即可。 代码如下&#xff08;不要忘记安装代码依赖的库&#xff09;&#xff1a; # -*- co…...

代码随想录算法训练营第39天 | ● 62.不同路径 ● 63. 不同路径II

文章目录 前言一、62.不同路径二、63.不同路径II总结 前言 动态规划 一、62.不同路径 深搜动态规划数论 深搜&#xff1a; 注意题目中说机器人每次只能向下或者向右移动一步&#xff0c;那么其实机器人走过的路径可以抽象为一棵二叉树&#xff0c;而叶子节点就是终点&#…...

《网站建设:从规划到发布的全过程详解》

一、引言 在数字时代&#xff0c;网站已经成为企业和个人在互联网上的重要存在。一个优质网站的建立需要周全的规划、设计、开发、测试和发布。本文将详细介绍网站建设的全过程&#xff0c;帮助读者了解和掌握网站建设的流程和方法。 二、网站建设的意义 网站建设具有以下意…...

1分钟实现 CLIP + Annoy + Gradio 文搜图+图搜图 系统

多模态图文搜索系统 CLIP 进行 Text 和 Image 的语义EmbeddingAnnoy 向量数据库实现树状结构索引来加速最近邻搜索Gradio 轻量级的机器学习 Web 前端搭建 文搜图 图搜图 CLIP图像语义提取功能&#xff01;...

用树形dp+状压维护树上操作的计数问题:0902T3

发现操作数 k ≤ 6 k\le6 k≤6&#xff0c;可以考虑对操作进行状压。 然后找找性质&#xff0c;发现要么删掉一棵子树&#xff0c;要么进去该子树。可以视为每种操作有两种情况。 然后分讨一下当前该如何转移。 树形dp的顺序&#xff1a; 合并子树考虑当前往上的边的方向 …...

【python爬虫】批量识别pdf中的英文,自动翻译成中文上

不管是上学还是上班,有时不可避免需要看英文文章,特别是在写毕业论文的时候。比较头疼的是把专业性很强的英文pdf文章翻译成中文。我记得我上学的时候,是一段一段复制,或者碰到不认识的单词就百度翻译一下,非常耗费时间。本文提供批量识别pdf中英文的方法,后续文章实现自…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...