Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >趣解设计模式之《小店儿菜单的故事》

趣解设计模式之《小店儿菜单的故事》

作者头像
爪哇缪斯
发布于 2023-09-26 06:05:26
发布于 2023-09-26 06:05:26
14500
代码可运行
举报
文章被收录于专栏:爪哇缪斯爪哇缪斯
运行总次数:0
代码可运行

〇、小故事

在一座小镇上,有两家特别有名气的小店,一家是远近闻名的早餐店,它家的早餐特别好吃,每天早上都能排起长长的队伍;另一家是个蛋糕店,他家是专门从法国请来的蛋糕师傅,蛋糕的香味真是香飘万里。

自从听说这个酱香拿铁销量非常高之后,这两家店的老板们就觉得强强联合才是能让小店更进一步的关键,所以,两家老板打算合并起来一起做生意。

但是呢,早餐店的菜单是ArrayList维护的,蛋糕店的菜单是数组维护的。那么对于服务员来说,他报菜单的时候,既要针对ArrayList类型的菜单进行遍历输出菜品,又需要再针对数组进行遍历输出菜品。并且,如果后面合并的小店越来越多,菜单用了其他的数据结构存储怎么办呢?如果强制所有的饭店都使用统一的集合类型去存储菜单的话,那么对小店来说,所有用到旧菜单的地方都需要代码修改。这样改动太大了呀。

为了解决这个问题,我们统一提供了迭代器接口,每个饭店的菜单都要实现迭代器这个接口。那么这就是今天要给大家介绍的设计模式——迭代器模式

一、模式定义

迭代器模式Iterator Pattern

提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

二、模式类图

针对上面两个小店合并后菜单类型不一致导致的遍历问题,我们来看一下如何采用迭代模式来解决。首先,我们要创建菜单接口类Menu,以及两个饭店的菜单实现类,分别是:ARestaurantMenuBRestaurantMenu。其次,创建菜单迭代器接口MenuIterator和两个饭店的菜单迭代器实现类,分别是:ARestaurantMenuIteratorBRestaurantMenuIterator。最后,创建服务员类Waitress和菜单项类MenuItem。具体类图请见如下所示:

三、代码实现

创建菜单明细项MenuItem.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MenuItem {
    // 菜名
    private String name;
    // 菜品详细介绍
    private String desc;
    // 是否是素食
    private boolean vegetarian;
    // 菜的价格
    private double price;

    public MenuItem(String name, String desc, boolean vegetarian, double price) {
        this.name = name;
        this.desc = desc;
        this.vegetarian = vegetarian;
        this.price = price;
    }
    /** xxxGet()和xxxSet()方法*/
}

创建小店菜单接口Menu.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface Menu {
    MenuIterator iterator(); // 获得迭代器
}

创建A饭店菜单实现类ARestaurantMenu.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ARestaurantMenu implements Menu {
    private ArrayList<MenuItem> menuItems;
    public ARestaurantMenu() {
        menuItems = new ArrayList<>();
        addItem("油条", "油条的描述", true, 0.5);
        addItem("豆浆", "豆浆的描述", true, 1.9);
        addItem("茶叶蛋", "茶叶蛋的描述", true, 1.5);
        addItem("小笼包", "小笼包的描述", true, 2.1);
    }

    private void addItem(String name, String desc, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, desc, vegetarian, price);
        menuItems.add(menuItem);
    }

    public ArrayList<MenuItem> getMenuItems() {
        return menuItems;
    }

    @Override
    public MenuIterator iterator() {
        return new ARestaurantMenuIterator(menuItems);
    }
}

创建B饭店菜单实现类BRestaurantMenu.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class BRestaurantMenu implements Menu {
    int nums = 0;
    private static final int MAX_SIZE = 5; // 餐厅老板很有个性,只做5道菜
    private MenuItem[] menuItems;

    public BRestaurantMenu() {
        menuItems = new MenuItem[MAX_SIZE];
        addItem("宫保鸡丁", "宫保鸡丁的描述", true, 0.5);
        addItem("北京烤鸭", "北京烤鸭的描述", true, 1.9);
        addItem("黄焖鸡米饭", "黄焖鸡米饭的描述", true, 1.5);
        addItem("啵啵鱼", "啵啵鱼的描述", true, 2.1);
        addItem("兰州拉面", "兰州拉面的描述", true, 2.1);
    }

    private void addItem(String name, String desc, boolean vegetarian, double price) {
        MenuItem menuItem = new MenuItem(name, desc, vegetarian, price);
        if (nums >= MAX_SIZE) {
            System.out.println("菜单满了!老板不做了!");
            return;
        }
        menuItems[nums++] = menuItem;
    }

    public MenuItem[] getMenuItems() {
        return menuItems;
    }

    @Override
    public MenuIterator iterator() {
        return new BRestaurantMenuIterator(menuItems);
    }
}

创建菜单迭代器接口类MenuIterator.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface MenuIterator {
    // 容器中是否还有元素
    boolean hasNext();
    // 获得容器中的下一个元素
    MenuItem next();
}

创建A饭店的菜单迭代器实现类ARestaurantMenuIterator.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ARestaurantMenuIterator implements MenuIterator {
    private ArrayList<MenuItem> menuItems;
    private Iterator<MenuItem> iterator;

    public ARestaurantMenuIterator(ArrayList<MenuItem> menuItems) {
        this.menuItems = menuItems;
        iterator = menuItems.iterator();
    }

    @Override
    public boolean hasNext() {
        return iterator.hasNext();
    }

    @Override
    public MenuItem next() {
        return iterator.next();
    }
}

创建B饭店的菜单迭代器实现类BRestaurantMenuIterator.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class BRestaurantMenuIterator implements MenuIterator {
    private MenuItem[] menuItems;
    private int i = 0;

    public BRestaurantMenuIterator(MenuItem[] menuItems) {
        this.menuItems = menuItems;
    }

    @Override
    public boolean hasNext() {
        return menuItems != null && i < menuItems.length && menuItems[i] != null;
    }

    @Override
    public MenuItem next() {
        return menuItems[i++];
    }
}

创建服务员类Waitress.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Waitress {
    /** 服务员打印菜单 */
    public void printMenu(Menu... menus) {
        for (Menu menu : menus) {
            print(menu.iterator());
        }
    }

    private void print(MenuIterator iterator) {
        MenuItem menuItem;
        while (iterator.hasNext()) {
            menuItem = iterator.next();
            System.out.println(String.format("name=%s, desc=%s, price=%s", menuItem.getName(), 
                                             menuItem.getDesc(), menuItem.getPrice()));
        }
    }
}

创建测试类IteratorTest.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class IteratorTest {
    public static void main(String[] args) {
        /** 构建A餐馆和B餐馆的菜单 */
        ARestaurantMenu aMenu = new ARestaurantMenu();
        BRestaurantMenu bMenu = new BRestaurantMenu();
        /** 构建女服务员 */
        Waitress waitress = new Waitress();
        /** 将A餐馆和B餐馆的菜单传给服务员,让她报出菜单来 */
        waitress.printMenu(aMenu, bMenu);
    }
}

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-26 09:30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爪哇缪斯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
趣解设计模式之《小店儿菜单的故事》
在一座小镇上,有两家特别有名气的小店,一家是远近闻名的早餐店,它家的早餐特别好吃,每天早上都能排起长长的队伍;另一家是个蛋糕店,他家是专门从法国请来的蛋糕师傅,蛋糕的香味真是香飘万里。
爪哇缪斯
2023/09/14
1840
趣解设计模式之《小店儿菜单的故事》
用C# (.NET Core) 实现迭代器设计模式
本文的概念来自深入浅出设计模式一书 项目需求 有两个饭店合并了, 它们各自有自己的菜单. 饭店合并之后要保留这两份菜单. 这两个菜单是这样的: 菜单项MenuItem的代码是这样的: 最初我们是这样设
solenovex
2018/04/28
7920
用C# (.NET Core) 实现迭代器设计模式
【万字图文】详解设计模式(下篇)
本篇关于设计模式的文章是设计模式的下篇,上下两篇文章介绍了整个23种设计模式中的22种,由于解释器模式主要应用场景是在解释器开发中,所以,该模式就只列举出了一些含义和使用场景,并没有类图和示例。而其他的22种设计模式,基本遵循的是:待解决的问题——>应用场景——>模式定义——>类图——>具体实现——>优缺点,这几方面来介绍的。那么,话不多说了,还是老样子,如下为本篇文章的整体目录:
爪哇缪斯
2023/05/10
1.2K0
【万字图文】详解设计模式(下篇)
常用设计模式——迭代器模式
迭代器模式 概念 提供一种方法顺序访问一个集合中的各个元素,而又不暴露其内部实现。 示例 演示了迭代器模式,遍历餐厅菜单的例子 /** * 菜单项 * @author huangy on 2019
用户5325874
2020/01/16
5780
常用设计模式——迭代器模式
迭代器模式
有两家餐厅,共有两个菜单,两家准备合并,每个餐厅都有一个销售系统,但是内部菜单的组成结构稍有不同,一个是用数组存储菜单对象,一个是用集合存储菜单对象
杨小杰
2019/07/04
5600
迭代器模式
Head First设计模式——迭代器模式
前言:迭代器模式平时用的不多,因为不管C#还是Java都已经帮我封装了,但是你是否知道平时经常在用的东西本质是怎么回事呢。
SpringSun
2020/08/11
3570
Head First设计模式——迭代器模式
设计模式之迭代器与组合模式(二)
在上次的文章中,我们通过层层引导,已经知道了迭代器模式的由来。现在我们再好好总结下。
程序员小跃
2019/12/25
4640
组合模式.
组合部件为叶子节点和组合节点定义了统一的接口。所有的操作,如果子类没有实现,我们默认抛出一个 UnsupportedOperationException 异常。
JMCui
2019/01/03
8050
设计模式之迭代器与组合模式(四)
我们要如何在菜单上应用组合模式呢?一开始,我们需要创建一个组件接口来作为菜单和菜单项的共同接口,让我们能够用统一的做法来处理菜单和菜单项。换句话说,我们可以针对菜单或菜单项调用相同的方法。
程序员小跃
2019/12/27
3400
设计模式之迭代器与组合模式(四)
设计之禅——迭代器模式
迭代器想必大家不会陌生,作为Java中内置的API,平时我们使用的也是非常多的。但你是否曾想过它和迭代器模式有什么关联?并且Java中已经有for循环遍历,为什么还会需要这样一个类?
夜勿语
2020/09/07
2930
使用C# (.NET Core) 实现组合设计模式 (Composite Pattern)
本文的概念性内容来自深入浅出设计模式一书. 本文需结合上一篇文章(使用C# (.NET Core) 实现迭代器设计模式)一起看. 上一篇文章我们研究了多个菜单一起使用的问题. 需求变更 就当我们感觉我
solenovex
2018/05/30
1.1K0
设计模式之组合模式
组合模式:将对象聚合成树形结构来表现“整体/部分”的层次结构。 组合模式能让客户以一致的方式来处理个别对象以及对象组合。 也就是我们可以忽略对象组合与个体对象之间的差别
用户9854323
2022/06/25
1970
设计模式之组合模式
设计模式----迭代器模式
迭代器模式: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表现。 示例:餐厅和煎饼屋合并后,需要遍历菜单时,由于餐厅菜单使用的是数组,而煎饼屋使用的是ArrayList,怎么才能统一地用一种方法来遍历呢? 由于Java内置对迭代器的支持,我们利用javautil.Iterator包来实现。 首先看一下iterator接口: <<interface>>iterator hasNext() next() remove() hasNext() next() remove
SuperHeroes
2018/05/30
4820
设计模式之迭代器模式 引导篇
这两天,比较火的并购新闻就是,网易考拉被阿里以20亿美元收购。从此网易考拉不再姓“网”而姓“阿”了。并购后的网易考拉和阿里的电商系统进行对接。那么问题来了:在阿里有个早餐店的菜单(CakeHouseMenu)使用的事ArrayList来存放菜单的,考拉有个午餐店的菜单(DinerMenu)使用的是数组结构存放的。现在考拉和阿里合并了,两个点的菜单也要合并。
凯哥Java
2019/09/07
4800
设计模式之迭代器模式 引导篇
HeadFirst设计模式
抽象父类只负责实现相应功能不用管具体是哪一个实现。 子类想调用哪一个行为,就new一个新的行为。
Tim在路上
2020/08/04
3650
Head First设计模式——组合模式
  组合模式的例子我们继续延续上篇《Head First设计模式——迭代器模式》的菜单例子,首先声明下迭代器和组合模式没有什么关系,他们是两个不同模式。只是我们在这个菜单例子的组合模式内部会用到迭代器。
SpringSun
2020/08/11
4770
Head First设计模式——组合模式
设计模式-迭代器模式
迭代器模式(Iterator Pattern)是一种行为型设计模式,它可以让我们在不暴露对象实现细节的情况下,访问一个聚合对象中的每一个元素,而无需暴露其内部结构。迭代器模式通过将聚合对象的遍历操作委托给一个迭代器对象来实现这一目标。迭代器模式提供了一种标准的遍历方式,使得我们可以在不改变聚合对象代码的情况下,实现对聚合对象的不同遍历方式。
堕落飞鸟
2023/05/04
1630
设计模式之迭代器与组合模式(一)
很高兴,这本书总共13章,这次已经是到第9章了;同时也很遗憾,小编脱离了书本,还是不知道如何描述一个设计模式。就比如迭代器与组合模式,原书篇幅比较长,小编尽量通俗易懂些,不到之处,还请各位小伙伴参考原书,小编也欢迎和大家一起交流。
程序员小跃
2019/12/26
4330
设计模式——迭代器模式
设计模式——迭代器模式
Java架构师必看
2021/05/14
3710
设计模式——迭代器模式
图解Java设计模式之迭代器模式
编写程序展示一个学校院系结构 :需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。如图 :
海仔
2020/04/01
4440
图解Java设计模式之迭代器模式
相关推荐
趣解设计模式之《小店儿菜单的故事》
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验