迭代器模式的理解和示例

一、是什么

1. 定义: 在对象集合之间游走,而不暴露集合的实现

二、示例

代理背景:

  1. 有汉堡包店和晚餐店的菜单, 假设汉堡包店的菜单是用List存放, 晚餐店是用数组存放的(用不同的存放方式,为了体现迭代器统一的处理方式)

  2. 服务生要将两家店的菜单都打印出来

  3. 这里先自己重写Iterator, 为了体现迭代器的设计模式,在实际使用中,可以直接循环Iterator

2.1 菜单项 Menu, 菜单有名称和价格

/**
 * 菜单
 */
public class Menu {
   private String name;
   private Double price;

    public Menu(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

2.2 晚餐店, 注意这里是用数组存放菜单的

/**
 * 晚餐店
 */
public class DinnerShop {

    private static final int MAX_ITEMS = 4;
    int index = 0;
    Menu[] menuItems;

    public DinnerShop() {
        menuItems = new Menu[MAX_ITEMS];

        // 默认就放入菜单项
        addItem("浪漫晚餐", 299d);
        addItem("小龙虾", 99d);
        addItem("鱿鱼", 49d);
        addItem("扇贝", 89d);
    }

    public void addItem(String name, double price) {
        Menu menu = new Menu(name, price);
        if (index >= MAX_ITEMS) {
            System.err.println("对不起, 菜单页满了");
        } else {
            menuItems[index] = menu;
            index++;
        }
    }

    // 创建迭代器:重点
    public Iterator createIteraotr() {
        return new DinnerMenuIterator(menuItems);
    }
}

晚餐点菜单迭代器, 重写next()和hasNext()方法

/**
 * 晚餐菜单遍历类
 */
public class DinnerMenuIterator implements Iterator {
    Menu[] menuItems;
    int position = 0;

    public DinnerMenuIterator(Menu[] menuItems) {
        this.menuItems = menuItems;
    }

    @Override
    public boolean hasNext() {
        if (position >= menuItems.length || menuItems[position] == null) {
            return false;
        }

        return true;
    }

    @Override
    public Object next() {
        Menu menuItem = menuItems[position];
        position++;
        return menuItem;
    }
}

2.3 汉堡包店, 这里用List存放菜单

/**
 * 汉堡店菜单
 */
public class PancakeHouseShop {

    /**
     * 菜单列表
     */
    List<Menu> menuItems;

    public PancakeHouseShop() {
        this.menuItems = new ArrayList<>();

        // 默认就放入菜单项
        addItem("可乐", 3d);
        addItem("汉堡", 13d);
        addItem("薯条", 8d);
        addItem("鸡翅", 5d);
    }

    public void addItem(String name, Double price) {
        Menu menu = new Menu(name, price);
        menuItems.add(menu);
    }

    // 产生迭代器
    public Iterator createIterator() {
        return new PancakeHouseMenuIterator(menuItems);
    }
}

汉堡包店迭代器

/**
 * 汉堡包菜单迭代类
 */
public class PancakeHouseMenuIterator implements Iterator {
    List<Menu> menuItems;
    int position = 0;

    public PancakeHouseMenuIterator(List<Menu> menuItems) {
        this.menuItems = menuItems;
    }

    @Override
    public boolean hasNext() {
        if (position >= menuItems.size() || menuItems.get(position) == null) {
            return false;
        }

        return true;
    }

    @Override
    public Object next() {
        Menu menuItem = menuItems.get(position);
        position++;

        return menuItem;
    }
}

2.4 测试类:服务生

/**
 * 服务生
 */
public class Waiter {

    public void print() {
        System.out.println("================== 汉堡包菜单 ======================");
        PancakeHouseShop pancakeHouseShop = new PancakeHouseShop();
        Iterator pancakeHouseMenuIterator = pancakeHouseShop.createIterator();
        printMenu(pancakeHouseMenuIterator);

        System.out.println("=================== 晚餐菜单 =====================");
        DinnerShop dinnerShop = new DinnerShop();
        Iterator dinnerMenuIterator = dinnerShop.createIteraotr();
        printMenu(dinnerMenuIterator);
    }

    private void printMenu(Iterator iterator) {
        while (iterator.hasNext()) {
            Menu menu = (Menu) iterator.next();
            System.out.println("名称: " + menu.getName() + "======== 价格: " + menu.getPrice());
        }
    }

    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        waiter.print();
    }
}

控制台打印:

================== 汉堡包菜单 ======================
名称: 可乐======== 价格: 3.0
名称: 汉堡======== 价格: 13.0
名称: 薯条======== 价格: 8.0
名称: 鸡翅======== 价格: 5.0
=================== 晚餐菜单 =====================
名称: 浪漫晚餐======== 价格: 299.0
名称: 小龙虾======== 价格: 99.0
名称: 鱿鱼======== 价格: 49.0
名称: 扇贝======== 价格: 89.0



三、总结

1. 这里没有用直接将数组和List生成Iterator, 是为了更方便的看出迭代器的作用

2. 用同一的方式来遍历,不暴露内部细节

原文地址:https://www.cnblogs.com/milicool/p/11278623.html

时间: 2024-10-05 17:04:18

迭代器模式的理解和示例的相关文章

命令模式的理解和示例

一.是什么?作用 1. 命令模式 将“请求”封装成对象,以使用不同的请求队列或者日志来参数话其他对象,命令模式亦可以来支持撤销的操作 2. 将请求封装成命令对象,请求的具体执行由命令接收者执行: 作用: 命令发送者与命令执行者解耦: 每一个命令都是一个操作 3. 类图 Invoke(调用者): 调用者负责执行命令 Command(命令接口): 负责将操作封装成统一的方法 Concreatecommand(命令实现类): 负责将命令真正执行者的操作封装起来 Receiver(接受者): 命令的真正

设计模式之迭代器模式详解(foreach的精髓)

作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,很久没以LZ的身份和各位对话了,前段时间为了更加逼真的解释设计模式,LZ费尽心思给设计模式加入了故事情节,本意是为了让各位在看小说的过程中就可以接触到设计模式,不过写到现在,LZ最深的感触就是,构思故事的时间远远超过了LZ对设计模式本身的研究. 本章介绍迭代器模式,不再采用故事嵌入的讲解方式,主要原因是因为迭代器模式本

深入理解JavaScript系列(35):设计模式之迭代器模式

介绍 迭代器模式(Iterator):提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示. 迭代器的几个特点是: 1.访问一个聚合对象的内容而无需暴露它的内部表示. 2.为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作. 3.遍历的同时更改迭代器所在的集合结构可能会导致问题(比如C#的foreach里不允许修改item). 正文 一般的迭代,我们至少要有2个方法,hasNext()和Next(),这样才做做到遍历所有对象,我们先给出一个例子: v

用最简单的例子理解迭代器模式(Iterator Pattern)

迭代器模式的需求来自:需要对一些集合进行迭代,而迭代的方式可能有很多种. 说到迭代,动作大致包括设置第一个位置,获取下一个位置元素,判断是否迭代结束,获取当前位置元素,大致就这么些.把这些迭代动作封装到一个接口中. public interface IIterator { void First(); string Next(); bool IsDone(); string Current(); } 在现实场景中,迭代的方式可能有很多种,先实现一种迭代方式,实现IIterator接口. publi

GOF23设计模式之迭代器模式理解与实现

 迭代器模式      场景:          提供一种可以遍历聚合对象的方式.又称为游标cursor模式          聚合对象:存储数据          迭代器模式:遍历数据   聚集抽象类 Aggregate Iterator 迭代抽象类,用于定义得到开始对象,得到下一个对象,判断是否到结尾,当前对象等抽象方法,统一接口 具体聚集类:继承Aggregate 具体迭代器类,继承Iterator,实现开始,下一个,是否结尾,当前对象等方法.   使用场景:      前向迭代器  

C#设计模式(16)——迭代器模式(Iterator Pattern)

一.引言 在上篇博文中分享了我对命令模式的理解,命令模式主要是把行为进行抽象成命令,使得请求者的行为和接受者的行为形成低耦合.在一章中,将介绍一下迭代器模式.下面废话不多说了,直接进入本博文的主题. 二.迭代器模式的介绍 迭代器是针对集合对象而生的,对于集合对象而言,必然涉及到集合元素的添加删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作也放在集合对象中,但这样的话,集合对象就承担太多的责任了,面向对象设计原则中有一条是单一职责原则,所以我们要尽可能地分离这些职责,用不同的类去

16.设计模式_迭代器模式

一.引言 在上篇博文中分享了我对命令模式的理解,命令模式主要是把行为进行抽象成命令,使得请求者的行为和接受者的行为形成低耦合.在一章中,将介绍一下迭代器模式.下面废话不多说了,直接进入本博文的主题. 二.迭代器模式的介绍 迭代器是针对集合对象而生的,对于集合对象而言,必然涉及到集合元素的添加删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作也放在集合对象中,但这样的话,集合对象就承担太多的责任了,面向对象设计原则中有一条是单一职责原则,所以我们要尽可能地分离这些职责,用不同的类去

C#设计模式-迭代器模式

一. 迭代器(Iterator)模式 迭代器是针对集合对象而生的,对于集合对象而言,必然涉及到集合元素的添加删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作也放在集合对象中,但这样的话,集合对象就承担太多的责任了,面向对象设计原则中有一条是单一职责原则,所以我们要尽可能地分离这些职责,用不同的类去承担不同的职责.迭代器模式就是用迭代器类来承担遍历集合元素的职责. 迭代器模式提供了一种方法顺序访问一个聚合对象(理解为集合对象)中各个元素,而又无需暴露该对象的内部表示,这样既可以做

java集合类中的迭代器模式

不说模式的问题,看一个<<设计模式之禅>>里面的例子. 老板要看到公司了各个项目的情况.(我知道我这个概述很让人头大,看代码吧) 示例程序 v1 package Iterator; /** * @author cbf4Life [email protected] * 定义一个接口,所有的项目都是一个接口 */ public interface IProject { //从老板这里看到的就是项目信息 public String getProjectInfo(); } package