什么是迭代器、组合模式
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露内部的表示。
组合模式:允许你将组合对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合
实现了组合模式的小例子
餐厅里边有供应早餐,午餐和晚餐,每餐供应的餐食又不同,我们要做的就是使用组合模式打印所有菜单
首先有一个所有菜单的基类,所有的菜单都必须继承自该类,里边关于菜单的操作我们都交给具体的菜单类去完成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public abstract class MenuComponent { public void add(MenuComponent menuComponent){ throw new UnsupportedOperationException(); } public void remove(MenuComponent menuComponent){ throw new UnsupportedOperationException(); } public MenuComponent getChild(int i){ throw new UnsupportedOperationException(); } public String getName(){ throw new UnsupportedOperationException(); } public String getDescription(){ throw new UnsupportedOperationException(); } public double getPrice(){ throw new UnsupportedOperationException(); } public boolean isVegetarian(){ throw new UnsupportedOperationException(); } public void print(){ throw new UnsupportedOperationException(); } public Iterator createIterator(){ throw new UnsupportedOperationException(); } }
|
实现组合菜单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public class Menu extends MenuComponent { ArrayList menuComponents = new ArrayList(); String name; String description; public Menu(String name,String description){ this.name = name; this.description = description; } public void add(MenuComponent menuComponent){ menuComponents.add(menuComponent); } public void remove(MenuComponent menuComponent){ menuComponents.remove(menuComponent); } public MenuComponent getChild(int i){ return (MenuComponent) menuComponents.get(i); } public String getName(){ return name; } public String getDescription(){ return description; } public void print(){ System.out.print("\n"+getName()); System.out.println(", "+getDescription()); System.out.println("这里是分割线======>"); Iterator iterator = menuComponents.iterator(); while(iterator.hasNext()){ MenuComponent menuComponent = (MenuComponent)iterator.next(); menuComponent.print(); } } public Iterator createIterator(){ return new CompositeIterator(menuComponents.iterator()); } }
|
实现菜单项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class MenuItem extends MenuComponent { String name; String description; boolean vegetarian; double price; public MenuItem(String name,String description,boolean vegetarian,double price){ this.name = name; this.description = description; this.vegetarian = vegetarian; this.price = price; } public String getName(){ return name; } public String getDescription(){ return description; } public double getPrice(){ return price; } public boolean isVegetarian(){ return vegetarian; } public void print(){ System.out.print(" "+getName()); if(isVegetarian()){ System.out.print("(v)"); } System.out.println(", "+getPrice()); System.out.println(" --"+getDescription()); } public Iterator createIterator(){ return new NullIterator(); } }
|
菜单和菜单项类我们都有了,接下来要让服务员把菜单提供给客户看(打印出来)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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("\n素食菜单\n-----"); while(iterator.hasNext()){ MenuComponent menuComponent = (MenuComponent)iterator.next(); try { if(menuComponent.isVegetarian()){ menuComponent.print(); } }catch (UnsupportedOperationException e){} } } }
|
做一个测试类测试一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class MenuTestDrive { public static void main(String[] args){ MenuComponent pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU","供应早餐"); MenuComponent dinnerMenu = new Menu("DINNER MENU","供应午餐"); MenuComponent cafeMenu = new Menu("CAFE MENU","供应晚餐"); MenuComponent dessertMenu = new Menu("DESSERT MENU","餐后甜点"); MenuComponent allMenu = new Menu("ALL MENUS","全部菜单组合"); allMenu.add(pancakeHouseMenu); allMenu.add(dinnerMenu); allMenu.add(cafeMenu); dinnerMenu.add(new MenuItem("Pasta","好吃的意大利面",true,3.89)); dinnerMenu.add(dessertMenu); dessertMenu.add(new MenuItem("Apple Pie","好吃的苹果饼",true,1.59)); Waitress waitress = new Waitress(allMenu); waitress.printMenu(); } }
|
打印结果
ALL MENUS, 全部菜单组合
这里是分割线======>
PANCAKE HOUSE MENU, 供应早餐
这里是分割线======>
DINNER MENU, 供应午餐
这里是分割线======>
Pasta(v), 3.89
–好吃的意大利面
DESSERT MENU, 餐后甜点
这里是分割线======>
Apple Pie(v), 1.59
–好吃的苹果饼
CAFE MENU, 供应晚餐
这里是分割线======>
总结
1.迭代器允许访问聚合的元素,而不需要暴露它的内部结构
2.迭代器将遍历聚合的工作封装进一个对象中
3.当使用迭代器的时候,我们依赖聚合提供遍历
4.迭代器提供了一个通用的接口,让我们遍历聚合项,当我们的编码使用聚合的项时,就可以使用多态机制。
5.我们应该努力让一个类只分配一个责任
6.组合模式提供一个结构,可同时包容个别对像和组合对象
7.组合模式允许客户对个别对象以及组合对象一视同仁
8.组合结构内的任意对象称为组件,组件可以是组合,也可以是叶节点
9.在实现组合模式时,有许多设计上的折衷。要根据需要平衡透明性和安全性