思考题
咱们不仅仅要反对多个菜单,贬值还要反对菜单中的菜单。你如何解决这个新的设计需要? P355
【提醒】在咱们的新设计中,真正须要以下三点:
P354
- 咱们须要某种属性构造,能够包容菜单、子菜单和菜单项
- 咱们须要确定可能在每个菜单的各个项之间游走,而且至多要像当初用迭代器一样不便
- 咱们也须要可能更有弹性地在菜单项之间游走。比方说,可能只须要遍历甜点菜单,或者能够遍历餐厅的整个菜单(包含甜点菜单在内)
提供一个接口,对立菜单和菜单项的超类
- 接口蕴含菜单和菜单项的独特办法,菜单中执行办法是顺次执行每个子项中的雷同办法
- 接口蕴含菜单特有的增删改查子项的办法,菜单项中的增删改查子项的办法实现为间接抛出
UnsupportedOperationException
- 能够通过
instanceof
判断以后项是菜单还是菜单项
组合模式
容许你将对象组合成树形构造来体现”整体/局部“层次结构。组合能让客户以统一的形式解决个别对象以及对象组合。
特点
- 把雷同的操作利用在组合和个别对象上,即能够疏忽对象组合和个别对象之间的差异
P357
- 以违反繁多职责设计准则换取透明性,即岂但要治理层次结构,还要同时蕴含治理组合和叶节点的操作,以将组合和叶节点厚此薄彼
P367
空迭代器:空对象(命令模式中提到过)的一个例子。空迭代器, hasNext()
永远返回 false
, next()
永远返回 null
(集体感觉能够抛出 NoSuchElementException
), remove()
永远抛出 UnsupportedOperationException
。 P372
思考题
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