思考题

我们不仅仅要支持多个菜单,升值还要支持菜单中的菜单。你如何处理这个新的设计需求? P355

  • 【提示】在我们的新设计中,真正需要以下三点: P354

    • 我们需要某种属性结构,可以容纳菜单、子菜单和菜单项
    • 我们需要确定能够在每个菜单的各个项之间游走,而且至少要像现在用迭代器一样方便
    • 我们也需要能够更有弹性地在菜单项之间游走。比方说,可能只需要遍历甜点菜单,或者可以遍历餐厅的整个菜单(包括甜点菜单在内)
  • 提供一个接口,统一菜单和菜单项的超类
    • 接口包含菜单和菜单项的共同方法,菜单中执行方法是依次执行每个子项中的相同方法
    • 接口包含菜单特有的增删改查子项的方法,菜单项中的增删改查子项的方法实现为直接抛出 UnsupportedOperationException
    • 可以通过 instanceof 判断当前项是菜单还是菜单项

组合模式

允许你将对象组合成树形结构来表现”整体/部分“层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

特点

  • 把相同的操作应用在组合和个别对象上,即可以忽略对象组合和个别对象之间的差别 P357
  • 以违反单一职责设计原则换取透明性,即不但要管理层次结构,还要同时包含管理组合和叶节点的操作,以将组合和叶节点一视同仁 P367

空迭代器:空对象(命令模式中提到过)的一个例子。空迭代器, hasNext() 永远返回 falsenext() 永远返回 null (个人觉得可以抛出 NoSuchElementException), remove() 永远抛出 UnsupportedOperationExceptionP372

思考题

public class Waitress {
MenuComponent allMenus; public Waitress(MenuComponent allMenus) {
this.allMenus = allMenus;
} public void printMenu() {
allMenus.print();
} public void printVegetarianMenu() {
Iterator iterator = allMenus.createIterator();
System.out.println("\nVEGETARIAN MENU\n----");
while (iterator.hasNext()) {
MenuComponent menuComponent = (MenuComponent)iterator.next();
try {
if (menuComponent.isVegetarian()) {
menuComponent.print();
}
} catch (UnsupportedOperationException e) {}
}
}
}

printVegetarianMenu() 方法中只有菜单项的 print() 方法可以被调用,绝对不能调用菜单(组合)的 print() 方法。你能说出原因吗? P373

  • 使用迭代器遍历时已经会遍历所有的节点(包括组合节点和叶节点),而组合节点会打印所有子节点信息,如果调用组合节点的 print() ,则必定会重复打印某些叶节点。

思考题

配对下列模式和描述: P379

策略模式:封装可互换的行为,并使用委托决定使用哪一个

适配器模式:改变一个或多个类的接口

迭代器模式:提供一个方式来遍历集合,而无须暴露集合的实现

外观模式:简化一群类的接口

组合模式:客户可以将对象的集合以及个别的对象一视同仁

观察者模式:当某个状态改变时,允许一群对象能被通知到

所思所想

  • 以前在很多地方其实都用到了这种思想,二叉树、trie 树和线段树等树结构都允许将节点组成树形结构来表现”整体/部分“的层次结构,并且提供了一致的方式处理非叶节点和叶节点(非叶节点的方法内部按照特定逻辑处理和调用子节点的相同方法)

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

最新文章

  1. 让动态的 iframe 内容高度自适应
  2. iOS 系统分析(一) 阅读内核准备知识
  3. 【初级】linux rm 命令详解及使用方法实战
  4. mysql metadata lock(三)
  5. HDU3157 Crazy Circuits(有源汇流量有上下界网络的最小流)
  6. 使用PHP导入和导出CSV文件
  7. [OpenJudge 3064]坠落的蚂蚁
  8. PostgreSQL Replication之第十三章 使用PL/Proxy扩展(1)
  9. Educational Codeforces Round 15 D 数学推公式
  10. 一步步学Mybatis-实现单表情况下的CRUD操作 (3)
  11. apache 实用配置
  12. iOS 导航栏去阴影
  13. PHP方法实现1-9数列中添加‘+’,‘-’或'',使和为100,并输出数列
  14. 初识Java——一维数组的创建及使用
  15. 探索Windows命令行系列(4):通过命令操作文件和文件夹
  16. 通过Nginx使全站页面变灰
  17. C# web Api ajax发送json对象到action中
  18. Linux c读取系统内存使用信息
  19. [nginx] 从源码编译安装NGINX
  20. 启动Jenkins

热门文章

  1. 手把手教你写DI_1_DI框架有什么?
  2. ORCHARD WOODEN GATE
  3. CSP-S2020 浙江 游记
  4. Java集合源码分析(五)——HashMap
  5. 九、git学习之——git基本命令全总结
  6. 世界上最快的排序算法——Timsort
  7. Android 11 源码下载+编译教程
  8. 移动 WEB 开发的布局方式 ---- 响应式布局
  9. ubuntu 16.04安装adobe reader
  10. springmvc使用路径变量后再进行页面跳转会出现路径错误问题