共计 1604 个字符,预计需要花费 5 分钟才能阅读完成。
思考题
咱们不仅仅要反对多个菜单,贬值还要反对菜单中的菜单。你如何解决这个新的设计需要?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