思考题

public void printMenu() {
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
ArrayList breakfastItems = pancakeHouseMenu.getMenuItems(); DinerMenu dinerMenu = new DinerMenu();
MenuItem[] lunchItems = dinerMenu.getMenuItems(); for (int i = 0; i < breakfastItems.size(); ++i) {
MenuItem menuItem = (MenuItem) breakfastItems.get(i);
System.out.print(menuItem.getName() + " ");
System.out.println(menuItem.getPrice() + " ");
System.out.println(menuItem.getDescription());
} for (int i = 0; i < lunchItems.length; ++i) {
MenuItem menuItem = lunchItems[i];
System.out.print(menuItem.getName() + " ");
System.out.println(menuItem.getPrice() + " ");
System.out.println(menuItem.getDescription());
}
}

根据我们的 printMenu() 实现,下列哪一项为真? P322

  • [x] A. 我们是针对 PancakeHouseMenuDinerMenu 的具体实现编码,而不是针对接口。

    • 针对具体实现编程,没有解耦,无法动态替换
  • [ ] B. 女招待没有实现 Java 招待 API ,所以她没有遵守标准。
    • 女招待有一个招待规格,算是实现了一个隐式 API,并且内部实现封装了变化
  • [x] C. 如果我们决定从 DinerMenu 切换到另一种菜单,此菜单的项是用 Hashtable 来存放的,我们会因此需要修改女招待中的许多代码。
    • Hashtable 是一种新的具体实现,需要修改代码进行适配
  • [x] D. 女招待需要知道每个菜单如何表达内部的菜单项集合,这违反了封装。
    • 女招待的实现依赖菜单内部实现,与菜单强耦合,没有封装变化
  • [x] E. 我们有重复的代码; printMenu() 方法需要两个循环,来遍历两种不同的菜单。如果我们加上第三种菜单,我们就需要第三个循环。
    • 由于是针对菜单项集合的具体实现编程,所以增加新菜单就需要增加循环
  • [ ] F. 这个实现并没有基于 MXML(Menu XML),所以就没有办法互操作。
    • The implementation isn't based on MXML(Menu XML) and so isn't as interoperable as it shoule be.

    • 互操作性(英文:Interoperability;中文又称为:协同工作能力,互用性)作为一种特性,它指的是不同的系统和组织机构之间相互合作,协同工作(即互操作)的能力。就软件而言,互操作性——这条术语用来描述的是不同的程序(programs)借助于同一套交换格式(exchange formats)来交换数据,读写相同文件格式(file formats)以及采用相同协议(protocols)的能力。

    • 刚开始不懂,看了维基百科后的解释后有点似懂非懂。这个实现内部直接处理了不同数据格式,具有一定的互操作性。

思考题

请继续完成 PancakeHouseIterator 的实现,并对 PancakeHouseMenu 类做出必要的修改。 P327

public class PancakeHouseIterator implements Iterator {
ArrayList items;
int position = 0; public PancakeHouseIterator(ArrayList items) {
this.items = items;
} public Object next() {
return items.get(position++);
} public boolean hasNext() {
return position >= items.size();
}
} public class PancakeHouseMenu {
ArrayList menuItems; // 构造器和其他方法
// 移除 public ArrayList getMenuItems() 方法 public Iterator createIterator() {
return new PancakeHouseIterator(menuItems);
}
}

迭代器模式

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

特点
  • 遍历集合内部元素而不暴露内部表示 P336
  • 让聚合的接口和实现变得简洁 P336
  • 管理对象集合,不必理会遍历的事情 P336

思考题

迭代器模式的类图看起来很像我们所学过的另一个模式;你知道是哪个模式吗?提示:子类决定要创建哪个对象。 P337

  • 工厂方法模式

设计原则

单一职责原则:一个类应该只有一个引起变化的原因 P339

  • 高内聚:一个模块或一个类只支持一组相关的功能 P339
特点
  • 尽量将一个责任只指派给一个类 P339
  • 遵循单一职责原则的类是高内聚的 P339

思考题

请很快写下为了能让咖啡厅的菜单代码符合我们的框架,我们要对它做的三件事情: P342

public class CafeMenu {
HashTable menuItems = new Hashtable(); public CafeMenu() {
// 省略下述参数
// addItem(...);
// addItem(...);
// addItem(...);
} public void addItem(String name, String description, boolean vegetarian, double price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.put(menuItem.getName(), menuItem);
} public Hashtable getItems() {
return menuItems;
}
}
  • 实现 Menu 接口
  • 删除 getItems() 方法
  • 增加 createIterator() 方法

本文首发于公众号:满赋诸机(点击查看原文) 开源在 GitHub :reading-notes/head-first-design-patterns

Head First 设计模式 —— 10. 迭代器 (Iterator) 模式的更多相关文章

  1. 1、迭代器 Iterator模式 一个一个遍历 行为型设计模式

    1.Iterator模式 迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或者阵列)上遍访的接口,设计人员无需关心容器的内容. I ...

  2. 【设计模式大法】Iterator模式

    Iterator模式 --一个一个遍历 在Java中的for语句中 i++的作用是让 i 的值在每次循环后自增1,这样就可以访问数组中的下一个元素.下下一个元素.再下下一个元素,也就实现了从头至尾逐一 ...

  3. Java 实现迭代器(Iterator)模式

    类图 /** * 自己定义集合接口, 相似java.util.Collection * 用于数据存储 * @author stone * */ public interface ICollection ...

  4. 设计模式—迭代器Iterator模式

    什么是迭代器模式? 让用户通过特定的接口访问容器的数据,不需要了解容器内部的数据结构. 首先我们先模仿集合中ArrayList和LinkedList的实现.一个是基于数组的实现.一个是基于链表的实现, ...

  5. 设计模式C++描述----20.迭代器(Iterator)模式

    一. 举例说明 我们知道,在 STL 里提供 Iterator 来遍历 Vector 或者 List 数据结构. Iterator 模式也正是用来解决对一个聚合对象的遍历问题,将对聚合的遍历封装到一个 ...

  6. 设计模式——迭代器(Iterator)模式

    概述 迭代器模式简单的说(按我目前的理解)就是一个类提供一个对外迭代的接口,方面调用者迭代.这个迭代接口至少包括两个方法:hasNext()--用于判断是否还有下一个,next()--用于取出下一个对 ...

  7. JS常用的设计模式(10)——模版方法模式

    模式方法是预先定义一组算法,先把算法的不变部分抽象到父类,再将另外一些可变的步骤延迟到子类去实现.听起来有点像工厂模式( 非前面说过的简单工厂模式 ). 最大的区别是,工厂模式的意图是根据子类的实现最 ...

  8. 设计模式(10)--Facade(外观模式)--结构型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使 ...

  9. Java描述设计模式(10):组合模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.生活场景 1.文件系统 下图是常见的计算机文件系统的一部分. 文件系统是一个树结构,树上长有节点.树的节点有两种: 树枝节点 即文件夹,有 ...

  10. 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)

    原文:乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern) 作者:weba ...

随机推荐

  1. jq实现登陆页面的拖拽功能

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <script src ...

  2. SSIS -&gt;&gt; Parameter

    参数只能外部调用 参数分项目级别的参数和包级别的参数.项目级别的参数可见范围是所有包,而包级别的参数可见范围仅限于该包内. Sensitive选项是加密数据值,这样在Integration Servi ...

  3. iOS开发——短信验证码

    作为iOS开发者,大家都应该知道ShareSDK这个比较出名的第三方分享(带统计功能)开发工具包. 他的官网今年年初发布了短信验证码的SDK.本文介绍它的短信验证码SDK.(部分过程参考官网如何集成的 ...

  4. 清橙A1212:剪枝

    题面 清橙 Sol 一种新的树上\(DP\)姿势 从左往右按链\(DP\) 做法: 维护两个栈\(S1\),\(S2\) \(S1\)存当前的链 \(S2\)存分叉点以下要改的链 \(Dfs\),弄一 ...

  5. docker[caffe&amp;&amp;pycaffe]

    0 引言 今天花了一天,完成了整个caffe的dockerfile编写,其支持python3.6.6,这里主要的注意点是protobuf的版本(在3.6.0之后,只支持c11),还有在制作镜像的时候注 ...

  6. MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Sum, Aggregate, Avg

    开篇介绍 SSAS 分析服务中记录了大量的聚合值,这些聚合值在 Cube 中实际上指的就是度量值.一个给定的度量值可能聚合了来自事实表中上千上万甚至百万条数据,因此在设计阶段我们所能看到的度量实际上就 ...

  7. Python数据分析-Day2-Pandas模块

    1.pandas简介 Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标 ...

  8. 使用PerfView监测.NET程序性能(三):分组

    在上一篇博客中,我们通过Perfview帮助文件中自带的代码来简单使用了Perfview,了解了基本操作.现在来看看Perfview中的分组操作(Grouping).分组功能都旨将记录到的各种函数调用 ...

  9. rsync+inotify文件同步 - 同步慢的问题

    rsync+inotify文件同步 - 同步慢的问题 我们来看网上的教程,我加了注释.(网上所有的教程基本都一模一样,尽管写法不一样,致命点都是一样的) #!/bin/bash /usr/bin/in ...

  10. margin-top和padding-top

    padding- top 在原有的基础上进一步的扩张 margin - top 在原有的位置上发生上下的平移 <!DOCTYPE html> <html lang="en& ...