设计模式之迭代器与组合模式(一)

很高兴,这本书总共13章,这次已经是到第9章了;同时也很遗憾,小编脱离了书本,还是不知道如何描述一个设计模式。就比如迭代器与组合模式,原书篇幅比较长,小编尽量通俗易懂些,不到之处,还请各位小伙伴参考原书,小编也欢迎和大家一起交流。

有许多种方法可以把对象堆起来成为一个集合(collection)。你可以把它们放进数组、堆栈、列表或是散列表中,这是你的自由。每一种都有它自己的优点和适合的使用时机,但如果你想要遍历这些对象,怎么办呢?不用担心,接下来的学习就是如何能让客户遍历你的对象而又无法窥视你存储对象的方式;也将学习如何创建一些对象超集合,能够一口气就跳过某些让人望而生畏的数据结构。

对象村餐厅和对象村煎饼屋合并了

在面向对象的世界里,小伙伴们都开心的不要不要的,因为现在他们可以在同一个地方,享受煎饼屋美味的煎饼早餐,和好吃的餐厅午餐了。但是,有一点小麻烦......

煎饼屋记录的菜单项是使用数组来存储的,而餐厅是使用ArrayList记录他的菜单项,两家店长都不愿意改变现在的实现,毕竟有太多的代码依赖了,而我们又想减少依赖,用最小的改动。

两种表现形式会带来什么问题

想了解为什么有两种不同的菜单表现方式会让事情变得复杂化,让我们试着实现一个同时使用这两个菜单的客户代码。

我们新聘请了一位服务员,能应对顾客的需要打印定制的菜单,甚至告诉你是否某个菜单项是素食的,而无需询问厨师。要求如下:

  • printMenu():打印出菜单上的每一项
  • printBreakfastMenu():值打印早餐项
  • printLunchMenu():只打印午餐项
  • printVegetarianMenu():打印所有的素食菜单项
  • isItemVegetarian(name):指定项的名称,如果该项是素食的话,返回true,否则返回false

实现上来说,如下所示:

  1. 打印每份菜单上的所有项,必须调用PancakeHouseMenu和DinerMenu的getMenuItem()方法,来取得它们各自的带单项
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
ArrayList breakfastItems = pancakeHouseMenu.getMenuItems();

DinerMenu dinerMenu = new DinerMenu();
MenuItem[] lunchItems = dinerMenu.getMenuItems();
  1. 现在,分别打印里面的具体项目,早餐使用ArrayList,午餐使用数组
for (int i = 0; i < breakfastItems.size(); i++) {
MenuItem menuItem = (MenuItem)breakfastItems.get(i);
System.out.print(menuItem.getName());
System.out.println("\t\t" + menuItem.getPrice());
System.out.println("\t" + menuItem.getDescription());
}

for (int i = 0; i < lunchItems.length; i++) {
MenuItem menuItem = lunchItems[i];
System.out.print(menuItem.getName());
System.out.println("\t\t" + menuItem.getPrice());
System.out.println("\t" + menuItem.getDescription());
}
  1. 实现其他方法,做法也都和这一页的方法相类似。我们总是需要处理两个菜单,并且用两个循环遍历这些项。如果还有第三家餐厅以不同的实现出现,我们就需要有三个循环

下一步怎么办?

他们都不想改变自身的实现,因为意味着要重写许多代码。所以,如果我们能够找出一个方法,让他们的菜单实现一个相同的接口,这该多好呢。我们试试看封装。

这本书给我们最大的改变,就是封装变化的部分。在这里发生的变化是:由不同的集合类型所造成的遍历。能被封装吗?我们继续来分析下:

  1. 要遍历早餐项,我们需要使用ArrayList的size()和get()方法
for(int i = 0; i < breakfastItems.size(); i++) {
    MenuItem menuItem = (MenuItem)breakfastItems.get(i);
}
  1. 要遍历午餐项,我们需要使用数组的length字段和中括号
for (int i = 0; i < lunchItems.length; i++) {
    MenuItem menuItem = lunchItems[i];
}
  1. 现在我们创建一个对象,我们把它称为迭代器(Iterator),利用它来封装“遍历集合内的每个对象的过程”
Iterator iterator = breakfastMenu.createIterator();

while (iterator.hasNext()) {
    MenuItem menuItem = (MenuItem) iterator.next();
}
  1. 将它在数组上试试:
Iterator iterator = lunchMenu.createIterator();
while (iterator.hasNext()) {
    MenuItem menuItem = (MenuItem) iterator.next();
}

看到这里,可以看到,我们对遍历的封装已经奏效了;你大概已经猜到,这正是一个设计模式,称为迭代器模式。那我们放在下次来具体说说,等着噢。

爱生活,爱学习,爱感悟,爱挨踢

(0)

相关推荐

  • java范式与集合

    https://www.cnblogs.com/coderzjz/p/13587167.html 对象的容器,实现了对对象常用的操作 数组长度固定,集合长度不固定 数组可以存储基本类型和引用类型,集合 ...

  • 花了20天的时间给粉丝整理的一套"最全"的Java求职笔记(一)

    大家好,我是小编LRyab,公众号LRyab博客网,LRyab博客网是分享一些个人成长.思考方向.个人感悟.职业规划,博客涵盖java技术 vue. html. css.前端技术spring全家桶. ...

  • 2020最新总结大厂Java高频面试题(含答案解析)

    前言 发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 这份面试题的包含的模块分为19个模 ...

  • 设计模式之迭代器与组合模式(二)

    在上次的文章中,我们通过层层引导,已经知道了迭代器模式的由来.现在我们再好好总结下. 关于迭代器模式,你所需要知道的第一件事情,就是它依赖于一个名为迭代器的接口.这是一个可能的迭代器的接口: 现在,我 ...

  • 设计模式之迭代器与组合模式(三)

    现在我们已经能愉快地看着一页一页罗列出来的菜单进行点菜了.现在又有的小伙伴希望能够加上一份餐后甜点的"子菜单".怎么办呢?我们不仅仅要支持多个菜单,甚至还要支持菜单中的菜单. 如果 ...

  • 设计模式(十)——组合模式(HashMap源码解析)

    设计模式(十)——组合模式(HashMap源码解析)

  • PHP设计模式之迭代器模式

    PHP设计模式之迭代器模式 一说到这个模式,就不得不提循环语句.在<大话设计模式>中,作者说道这个模式现在的学习意义更大于实际意义,这是为什么呢?当然就是被foreach这货给整得.任何语 ...

  • PHP设计模式之组合模式

    PHP设计模式之组合模式 互联网公司流行扁平化管理,也就是管理层级尽量少于或者不超过三层,作为一个底层的码农,你的CEO和你的职级也就相差3层以内.但是很多传统企业,则会有非常深的层级关系,从数据结构 ...

  • [PHP小课堂]PHP设计模式之迭代器模式

    [PHP小课堂]PHP设计模式之迭代器模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • [PHP小课堂]PHP设计模式之组合模式

    [PHP小课堂]PHP设计模式之组合模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • C#设计模式-组合模式(Composite Pattern)

    概念 组合是一种结构型设计模式, 你可以使用它将对象组合成树状结构, 并且能像使用独立对象一样使用它们. 组合模式(Composite Pattern)是将对象组合成树形结构以表示'部分-整体'的层次 ...

  • 软件设计模式修炼 -- 迭代器模式

    迭代器模式是一种使用频率非常高的设计模式,迭代器用于对一个聚合对象进行遍历.通过引入迭代器可以将数据的遍历功能从聚合对象中分离出来,聚合对象只负责存储数据,聚合对象只负责存储数据,而遍历数据由迭代器来 ...