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

一、迭代器模式概述

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

  • 迭代器模式的优缺点
    • 优点
      • 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()方法会检查我们是否已经取得数组内所有的元素。
    // 如果还有元素待遍历,则返回true
    public 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 stub
		PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();        
        DinnerMenu dineMenu = new DinnerMenu();
        /**
         *两个菜单都实现一样的方法,但是并没有实现相同的接口,
         *女招待还是要依赖两个具体实现的菜单类
         *后面就要修改这里
         *
         */
        Waitress waitress = new Waitress(pancakeHouseMenu, dineMenu);
        waitress.printMenu();
	}

}
        2.7 UML图

三、代码结构图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uni-app开发canvas绘图画画,记录每一步画的信息, 并实现后退功能

在uni-app中,要实现canvas绘图并记录每一步的信息以实现后退功能,你需要做几件事: 初始化Canvas上下文:首先,你需要在页面加载时初始化canvas上下文。 记录绘图步骤:在绘图过程中,你需要记录每…

20240416,深拷贝浅拷贝,对象初始化和清理,对象模型和THIS指针

哈哈哈乌龟越狱了 目录 2.5 深拷贝&浅拷贝 2.6 初始化列表 2.7 类对象作为类成员 2.8 静态成员 2.9 成员变量和成员函数分开存储 2.10 THIS指针的用途 2.11 空指针访问成员函数 2.12 COSNT修饰成员函数 2.5 深拷贝&浅拷贝 浅拷贝:简单的赋值拷贝…

揭秘分销系统:商业模式的新风向

大家好,我是微三云周丽,今天给大家分析当下市场比较火爆的商业模式! 小编今天跟大伙们分享什么是分销系统? 在数字化浪潮席卷全球的今天,电子商务以其独特的优势,正在重塑商业世界的格局。其中&#xff0…

css设置输入框边框无效或者不展示边框

bug描述:在聚焦的时候,期望输入框的边框是主题色,但是不知道是个啥颜色。 发现输入框input以及textarea样式css标签:focus更改样式无效这个问题。 若希望实现input在触发焦点时更改样式,通常会想到使用:focus选择器,…

积极探索新质生产力,九河云携手华为云技术交流引领数智跃迁

4月18日,九河云携手华为云举办了华为云SA技术培训会议,培训邀请到华为云技术人员作为主讲人,通过理论讲解与案例结合的方式,围绕ECS和EBS之间的联动,调优和数据保护等方面展开,深入浅出地讲解了基于EBS部署…

uniapp 引用组件后 不起作用 无效果 不显示

根据uniapp官方文档easycom组件规范 只要组件安装在项目的components目录下或uni_modules目录下,并符合components/组件名称/组件名称.(vue|uvue)目录结构(注意:当同时存在vue和uvue时,uni-app 项目优先使用 vue 文件,…

浅谈防火墙,IPS,APT威胁检测的互补性

在学习网络安全产品时发现很多产品的目的与功能大同小异都是防范非法流量或威胁,但是既然有产品的差异就有作用的目的的差异,下面浅谈一下三个网络安全产品的差异化与互补点 防火墙 传统防火墙主要是工作在二到四层,不会对报文的载荷进行检…

App Cleaner Uninstaller中文激活版:mac最强深度清理软件

App Cleaner & Uninstaller 是一款适用于 Mac 操作系统的软件应用程序,允许用户轻松卸载不需要的应用程序、删除剩余文件和文件夹以及管理启动项。该应用程序会分析与您要删除的应用程序关联的文件,并帮助识别其所有组件,以便您可以一次将…

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

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

JsonPath实战

概述 JsonPath&#xff0c;GitHub是一种简单的方法来提取给定JSON文档的部分内容&#xff0c;提供类似正则表达式的语法来解析JSON文档。 特性 入门 引入如下Maven依赖&#xff1a; <dependency><groupId>com.jayway.jsonpath</groupId><artifactId&…

用Python将原始边列表转换为邻接矩阵

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在图论和网络分析中&#xff0c;图是一种非常重要的数据结构&#xff0c;它由节点&#xff…

驱动比例换向阀放大器

比例换向阀放大器技术是电液比例系统中关键的组成部分&#xff0c;它主要用于控制比例阀&#xff0c;实现对液压流量或压力的精确控制。 高精度控制&#xff1a;通过比例阀放大器&#xff0c;系统可以非常精确地调节液压流量或压力&#xff0c;这对于要求精密操作的机械系统来说…

DSP系统的设计过程与选型

DSP的设计步骤分几个阶段&#xff0c;应用系统的设计过程如图所示。 技术指标的确定 器件的选型原则 其他因素的考虑

学习c语音的自我感受

因为是自学&#xff0c;所以走过不少弯路。去年&#xff0c;受知乎“python性能弱”风潮的影响&#xff0c;学过go,rust。 在学习这些新语言的时候&#xff0c;由衷感受到&#xff0c;或是本身侧重方向的原因&#xff08;如go侧重服务器&#xff09;&#xff0c;或是语言太新不…

Php-WebView 现代跨平台 GUI分享

GitHub :php-webview 一个用于 C/C 的小型跨平台 Web 视图库&#xff0c;用于构建现代跨平台 GUI。 该项目的目标是为最广泛使用的平台创建一个通用的 HTML5 UI 抽象层。 它支持双向 JavaScript 绑定&#xff08;从 C/C 调用 JavaScript 和从 JavaScript 调用 C/C&#xff09;。…

蛋白质致病突变的计算方法(四)

3.1.5 域定位 (domain location) 残基在序列中的位置可分为N-terminal(1-30%)、中间(31-70%)和C-terminal(71-100%)。Singh等人报告称&#xff0c;TP53的中心和高度保守的DNA结合域包含一簇体细胞错义突变&#xff0c;包括R175、G245、R248和R273。这些突变形成与DNA的直接接触…

Docker 部署 WordPress 并完成建站

什么是 WordPress WordPress 是使用 PHP 语言开发的博客平台&#xff0c;用户可以在支持 PHP 和 MySQL 数据库的服务器上架设属于自己的网站。也可以把 WordPress 当作一个内容管理系统&#xff08;CMS&#xff09;来使用。WordPress 是一款个人博客系统&#xff0c;并逐步演化…

DC-DC电源设计中电感选型详解

电感参数: DC-DC 电感选型步骤: 1, 根据 DC-DC 的输入输出特性计算所需的最小电感量。 (1)对于 Buck 型 DC-DC,计算公式如下 Lmin= 【Vout*(1-Vout/Vinmax)】/ (Fsw*Irpp ) 其中: Vinmax = maximum input voltage Vout = output voltage fsw = switching frequency…

第二届阿里巴巴大数据智能云上编程大赛亚军比赛攻略_北方的郎队

关联比赛: 第二届阿里巴巴大数据智能云上编程大赛-智联招聘人岗智能匹配 查看更多内容&#xff0c;欢迎访问天池技术圈官方地址&#xff1a;第二届阿里巴巴大数据智能云上编程大赛亚军比赛攻略_北方的郎队_天池技术圈-阿里云天池

Pytorch:张量的梯度计算

目录 一、自动微分简单介绍1、基本原理2、梯度计算过程3、示例&#xff1a;基于 PyTorch 的自动微分a.示例详解b.梯度计算过程c.可视化计算图 4、总结 二、为什么要计算损失&#xff0c;为何权重更新是对的&#xff1f;1、梯度下降数学原理2、梯度上升 三、在模型中使用自动微分…
最新文章