设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)

设计模式学习--迭代器模式(Iterator Pattern)

概述

———————————————————————————————————————————————————

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

把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。

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

OO原则

———————————————————————————————————————————————————

  • 封装变化
  • 多用组合,少用继承
  • 针对接口编程,不针对实现编程
  • 为交互对象之间的松耦合设计而努力
  • 类应该对扩展开放,对修改关闭
  • 依赖抽象,不要依赖具体类
  • 只和朋友交谈
  • 别找我,我会找你
  • 类应该只有一个改变的理由

要点

———————————————————————————————————————————————————

  • 迭代器允许访问聚合的元素,而不需要暴露它的内部结构
  • 迭代器将遍历聚合的工作封装进一个对象中。
  • 当使用迭代器的时候,我们依赖聚合提供遍历。
  • 迭代器提供一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合的项时,就可以使用多态机制。
  • 我们应该努力让一个类分配一个责任。
  • 组合模式提供一个结构,可同时包容个别对象和组合对象。
  • 组合模式允许客户对个别对象以及组合对象一视同仁。
  • 组合结构内的任意对象成为组件,组件可以是组合,也可以是叶节点。
  • 在实现组合模式时,有许多设计上的折衷。你要根据需要平衡透明性和安全性。

例子1

———————————————————————————————————————————————————

自定义迭代器

Iterator

package dinermerger;

/**
* 自定义迭代器接口
* @author wwj
*
*/
public interface Iterator {
boolean hasNext(); //是否还有下一个元素
Object next(); //返回下一个元素
}

实现迭代器

DinerMenuIterator

package dinermerger;

/**
* 实现一个具体的迭代器,为餐厅菜单服务
* @author Administrator
*
*/
public class DinerMenuIterator implements Iterator {
MenuItem[] items;
int position = 0; //记录当前数组遍历的位置 public DinerMenuIterator(MenuItem[] items) {
this.items = items;
} @Override
public boolean hasNext() {
if(position >= items.length || items[position] == null) {
return false;
} else {
return true;
}
} @Override
public Object next() {
MenuItem menuItem = items[position];
position = position + 1;
return menuItem;
} }

PancakeHouseMenuIterator

package dinermerger;

import java.util.ArrayList;

/**
* 煎饼屋菜单实现
* @author wwj
*
*/
public class PancakeHouseMenuIterator implements Iterator{
ArrayList menuItems;
int position = 0; public PancakeHouseMenuIterator(ArrayList menuItems) {
this.menuItems = menuItems;
} @Override
public boolean hasNext() {
if(position >= menuItems.size()) {
return false;
} else {
return true;
}
} @Override
public Object next() {
Object object = menuItems.get(position);
position = position + 1;
return object;
}
}

菜单项

package dinermerger;

/**
* 菜单项
* @author wwj
*
*/
public class MenuItem {
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;
} }

菜单

PancakeHouseMenu

package dinermerger;

import java.util.ArrayList;

/**
* 煎饼屋菜单实现
* @author wwj
*
*/
public class PancakeHouseMenu {
ArrayList menuItems;
public PancakeHouseMenu() {
menuItems = new ArrayList(); addItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99); addItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99); addItem("Blueberry Pancakes", "Pancakes made with fresh blueberries", true, 3.49); addItem("Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59); } /**
* 创建一个新的菜单项对象,传入每一个变量,然后将它加入到ArrayList中
* @param name 菜名
* @param description 叙述
* @param vegetarian 是否为素食
* @param price 价格
*/
public void addItem(String name, String description, boolean vegetarian, double price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.add(menuItem);
} /* public ArrayList getMenuItems() {
return menuItems;
}*/ public Iterator createIterator() {
return new PancakeHouseMenuIterator(menuItems);
}
}

DinerMenu

package dinermerger;

/**
* 餐厅菜单
* @author wwj
*
*/
public class DinerMenu {
static final int MAX_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems; //使用一个数组,所以可以控制菜单的长度,并且在取出菜单项的时候,不需要转型 public DinerMenu() {
menuItems = new MenuItem[MAX_ITEMS];
addItem("Vegetarian BLT",
"(Fakin') Bacon with lettuce & tomato on Whole wheat", true,
2.99); addItem("BLT", "Bacon with lettuce & tomato on Whole wheat", false,
2.99); addItem("Soup of the day",
"Soup of the day, with a side of potato salad", false, 3.29); addItem("Hotdog",
"A hot dog, with saurkraut, relish, onions, topped with cheese",
false, 3.05); addItem("Steamed Veggies and Brown Rice",
"Steamed vegetables over brown rice", true, 3.99);
addItem("Pasta",
"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
true, 3.89);
} private void addItem(String name, String description, boolean vegetarian, double price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
if(numberOfItems >= MAX_ITEMS) {
System.err.println("Sorry, menu is full! Can't add item to menu");
} else {
menuItems[numberOfItems] = menuItem;
numberOfItems = numberOfItems + 1;
}
} /**
* 增加了迭代器之后,这个方法就不需要了
* @return
*/
/*public MenuItem[] getMenuItems() {
return menuItems;
}*/ /**
* 用来从菜单项数组创建一个DinerMenuIterator,并将它返回给客户
*/
public Iterator createIterator() {
return new DinerMenuIterator(menuItems);
} }

女招待

package dinermerger;

/**
* 女招待类
* @author wwj
*
*/
public class Waitress {
PancakeHouseMenu pancakeHouseMenu;
DinerMenu dinerMenu; /**
*在这个构造器中,女招待照顾两个菜单
* @param pancakeHouseMenu
* @param dinerMenu
*/
public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
} public void printMenu() {
Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
System.out.println("MENU\n----\nBREAKFAST");
printMenu(pancakeIterator);
System.out.println("\nLUNCH");
printMenu(dinerIterator);
} private void printMenu(Iterator iterator) {
while(iterator.hasNext()) { //测试是否还有其他项
MenuItem menuItem = (MenuItem) iterator.next();
System.out.print(menuItem.getName() + ", ");
System.out.print(menuItem.getPrice() + " -- ");
System.out.println(menuItem.getDescription());
}
}
}

测试

package dinermerger;

public class MenuTestDrive {

	/**
* @param args
*/
public static void main(String[] args) {
PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
DinerMenu dinerMenu = new DinerMenu(); Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu); waitress.printMenu();
} }

结果:

MENU
----
BREAKFAST
K&B's Pancake Breakfast, 2.99 -- Pancakes with scrambled eggs, and toast
Regular Pancake Breakfast, 2.99 -- Pancakes with fried eggs, sausage
Blueberry Pancakes, 3.49 -- Pancakes made with fresh blueberries
Waffles, 3.59 -- Waffles, with your choice of blueberries or strawberries

LUNCH
Vegetarian BLT, 2.99 -- (Fakin') Bacon with lettuce & tomato on Whole wheat
BLT, 2.99 -- Bacon with lettuce & tomato on Whole wheat
Soup of the day, 3.29 -- Soup of the day, with a side of potato salad
Hotdog, 3.05 -- A hot dog, with saurkraut, relish, onions, topped with cheese
Steamed Veggies and Brown Rice, 3.99 -- Steamed vegetables over brown rice
Pasta, 3.89 -- Spaghetti with Marinara Sauce, and a slice of sourdough bread

例子2

———————————————————————————————————————————————————

利用java.util.Iterator来实现迭代器

提供一个Menu接口,让PancakeHouseMenu和DinerMenu都实现Menu接口,这样Waitress就不用依赖具体的菜单的问题,也不用依赖菜单项的具体实现了。

package dinermerger;

/**
* 这是一个简单的接口,让客户能够取得菜单项
* @author Administrator
*
*/
public interface Menu {
public Iterator createIterator();
}

DinerMenu

package dinermerger;

import java.util.Iterator;

/**
* 餐厅菜单
* @author wwj
*
*/
public class DinerMenu implements Menu{
static final int MAX_ITEMS = 6;
int numberOfItems = 0;
MenuItem[] menuItems; //使用一个数组,所以可以控制菜单的长度,并且在取出菜单项的时候,不需要转型 public DinerMenu() {
menuItems = new MenuItem[MAX_ITEMS];
addItem("Vegetarian BLT",
"(Fakin') Bacon with lettuce & tomato on Whole wheat", true,
2.99); addItem("BLT", "Bacon with lettuce & tomato on Whole wheat", false,
2.99); addItem("Soup of the day",
"Soup of the day, with a side of potato salad", false, 3.29); addItem("Hotdog",
"A hot dog, with saurkraut, relish, onions, topped with cheese",
false, 3.05); addItem("Steamed Veggies and Brown Rice",
"Steamed vegetables over brown rice", true, 3.99);
addItem("Pasta",
"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
true, 3.89);
} private void addItem(String name, String description, boolean vegetarian, double price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
if(numberOfItems >= MAX_ITEMS) {
System.err.println("Sorry, menu is full! Can't add item to menu");
} else {
menuItems[numberOfItems] = menuItem;
numberOfItems = numberOfItems + 1;
}
} /**
* 增加了迭代器之后,这个方法就不需要了
* @return
*/
/*public MenuItem[] getMenuItems() {
return menuItems;
}*/ /**
* 用来从菜单项数组创建一个DinerMenuIterator,并将它返回给客户
*/
public Iterator createIterator() {
return new DinerMenuIterator(menuItems);
} }

PancakeHouseMenu

不创建自己的迭代器,而是调用ArrayList的iterator()方法

package dinermerger;

import java.util.ArrayList;
import java.util.Iterator; /**
* 煎饼屋菜单实现
* @author wwj
*
*/
public class PancakeHouseMenu implements Menu{
ArrayList menuItems;
public PancakeHouseMenu() {
menuItems = new ArrayList(); addItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99); addItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99); addItem("Blueberry Pancakes", "Pancakes made with fresh blueberries", true, 3.49); addItem("Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.59); } /**
* 创建一个新的菜单项对象,传入每一个变量,然后将它加入到ArrayList中
* @param name 菜名
* @param description 叙述
* @param vegetarian 是否为素食
* @param price 价格
*/
public void addItem(String name, String description, boolean vegetarian, double price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.add(menuItem);
} /* public ArrayList getMenuItems() {
return menuItems;
}*/ public Iterator createIterator() {
return menuItems.iterator();
}
}

DinerMenuIterator

package dinermerger;

import java.util.Iterator;

/**
* 实现一个具体的迭代器,为餐厅菜单服务
* @author Administrator
*
*/
public class DinerMenuIterator implements Iterator {
MenuItem[] items;
int position = 0; //记录当前数组遍历的位置 public DinerMenuIterator(MenuItem[] items) {
this.items = items;
} @Override
public boolean hasNext() {
if(position >= items.length || items[position] == null) {
return false;
} else {
return true;
}
} @Override
public Object next() {
MenuItem menuItem = items[position];
position = position + 1;
return menuItem;
} @Override
public void remove() {
if(position <= 0) {
throw new IllegalStateException("You can't remove an item until you've done at least on next()");
}
if(items[position - 1] != null) {
for(int i = position - 1; i < (items.length - 1); i++) {
items[i] = items[i + 1];
}
items[items.length - 1] = null;
} } }

Waitress

package dinermerger;

import java.util.Iterator; 

/**
* 女招待类
* @author wwj
*
*/
public class Waitress {
// PancakeHouseMenu pancakeHouseMenu;
// DinerMenu dinerMenu;
Menu pancakeHouseMenu;
Menu dinerMenu; /**
*在这个构造器中,女招待照顾两个菜单
* @param pancakeHouseMenu
* @param dinerMenu
*/
public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
} public void printMenu() {
Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
System.out.println("MENU\n----\nBREAKFAST");
printMenu(pancakeIterator);
System.out.println("\nLUNCH");
printMenu(dinerIterator);
} private void printMenu(Iterator iterator) {
while(iterator.hasNext()) { //测试是否还有其他项
MenuItem menuItem = (MenuItem) iterator.next();
System.out.print(menuItem.getName() + ", ");
System.out.print(menuItem.getPrice() + " -- ");
System.out.println(menuItem.getDescription());
}
}
}

增加一个CafeMenu会变成以下这样

package dinermerger;

import java.util.Hashtable;
import java.util.Iterator; /**
* 咖啡厅菜单
* @author wwj
*
*/
public class CafeMenu implements Menu{
Hashtable menuItems = new Hashtable(); public CafeMenu() {
addItem("Veggie Burger and Air Fries",
"Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
true, 3.99);
addItem("Soup of the day",
"A cup of the soup of the day, with a side salad", false, 3.69);
addItem("Burrito",
"A large burrito, with whole pinto beans, salsa, guacamole",
true, 4.29);
} public void addItem(String name, String description, boolean vegetarian, double price) {
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.put(menuItem.getName(), menuItem);
} @Override
public Iterator createIterator() {
return menuItems.values().iterator();
}
}
package dinermerger;

import java.util.Iterator; 

/**
* 女招待类
* @author wwj
*
*/
public class Waitress {
// PancakeHouseMenu pancakeHouseMenu;
// DinerMenu dinerMenu;
Menu pancakeHouseMenu;
Menu dinerMenu;
Menu cafeMenu; /**
*在这个构造器中,女招待照顾两个菜单
* @param pancakeHouseMenu
* @param dinerMenu
*/
public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
} /**
* 新增一个cafeMenu
* @param pancakeHouseMenu
* @param dinerMenu
* @param cafeMenu
*/
public Waitress(Menu pancakeHouseMenu, Menu dinerMenu, Menu cafeMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
this.cafeMenu = cafeMenu;
} public void printMenu() {
Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
Iterator cafeIterator = cafeMenu.createIterator();
System.out.println("MENU\n----\nBREAKFAST");
printMenu(pancakeIterator);
System.out.println("\nLUNCH");
printMenu(dinerIterator);
System.out.println("\nDINNER");
printMenu(cafeIterator);
} private void printMenu(Iterator iterator) {
while(iterator.hasNext()) { //测试是否还有其他项
MenuItem menuItem = (MenuItem) iterator.next();
System.out.print(menuItem.getName() + ", ");
System.out.print(menuItem.getPrice() + " -- ");
System.out.println(menuItem.getDescription());
}
}
}

Test

package dinermerger;

public class MenuTestDrive {

	/**
* @param args
*/
public static void main(String[] args) {
// PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
// DinerMenu dinerMenu = new DinerMenu();
//
// Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu);
//
// waitress.printMenu(); Menu pancakeHouseMenu = new PancakeHouseMenu();
Menu dinerMenu = new DinerMenu();
Menu cafeMenu = new CafeMenu(); Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu, cafeMenu);
waitress.printMenu();
} }

结果:

MENU
----
BREAKFAST
K&B's Pancake Breakfast, 2.99 -- Pancakes with scrambled eggs, and toast
Regular Pancake Breakfast, 2.99 -- Pancakes with fried eggs, sausage
Blueberry Pancakes, 3.49 -- Pancakes made with fresh blueberries
Waffles, 3.59 -- Waffles, with your choice of blueberries or strawberries

LUNCH
Vegetarian BLT, 2.99 -- (Fakin') Bacon with lettuce & tomato on Whole wheat
BLT, 2.99 -- Bacon with lettuce & tomato on Whole wheat
Soup of the day, 3.29 -- Soup of the day, with a side of potato salad
Hotdog, 3.05 -- A hot dog, with saurkraut, relish, onions, topped with cheese
Steamed Veggies and Brown Rice, 3.99 -- Steamed vegetables over brown rice
Pasta, 3.89 -- Spaghetti with Marinara Sauce, and a slice of sourdough bread

DINNER
Soup of the day, 3.69 -- A cup of the soup of the day, with a side salad
Burrito, 4.29 -- A large burrito, with whole pinto beans, salsa, guacamole
Veggie Burger and Air Fries, 3.99 -- Veggie burger on a whole wheat bun, lettuce, tomato, and fries

为了让女招待更加有扩展性,我们这样做

package dinermerger;

import java.util.ArrayList;
import java.util.Iterator; /**
* 女招待类
* @author wwj
*
*/
public class Waitress {
// PancakeHouseMenu pancakeHouseMenu;
// DinerMenu dinerMenu;
// Menu pancakeHouseMenu;
// Menu dinerMenu;
// Menu cafeMenu;
ArrayList menus; /* *//**
*在这个构造器中,女招待照顾两个菜单
* @param pancakeHouseMenu
* @param dinerMenu
*//*
public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
} *//**
* 新增一个cafeMenu
* @param pancakeHouseMenu
* @param dinerMenu
* @param cafeMenu
*//*
public Waitress(Menu pancakeHouseMenu, Menu dinerMenu, Menu cafeMenu) {
this.pancakeHouseMenu = pancakeHouseMenu;
this.dinerMenu = dinerMenu;
this.cafeMenu = cafeMenu;
}*/ public Waitress(ArrayList menus) {
this.menus = menus;
} public void printMenu() {
/* Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
Iterator cafeIterator = cafeMenu.createIterator();
System.out.println("MENU\n----\nBREAKFAST");
printMenu(pancakeIterator);
System.out.println("\nLUNCH");
printMenu(dinerIterator);
System.out.println("\nDINNER");
printMenu(cafeIterator);*/
Iterator menuIterator = menus.iterator();
while(menuIterator.hasNext()) {
Menu menu = (Menu)menuIterator.next();
printMenu(menu.createIterator());
} } private void printMenu(Iterator iterator) {
while(iterator.hasNext()) { //测试是否还有其他项
MenuItem menuItem = (MenuItem) iterator.next();
System.out.print(menuItem.getName() + ", ");
System.out.print(menuItem.getPrice() + " -- ");
System.out.println(menuItem.getDescription());
}
}
}

测试的时候我们就可以这样

package dinermerger;

import java.util.ArrayList;

public class MenuTestDrive {

	/**
* @param args
*/
public static void main(String[] args) {
// PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu();
// DinerMenu dinerMenu = new DinerMenu();
//
// Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu);
//
// waitress.printMenu(); Menu pancakeHouseMenu = new PancakeHouseMenu();
Menu dinerMenu = new DinerMenu();
Menu cafeMenu = new CafeMenu(); // Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu, cafeMenu);
ArrayList menus = new ArrayList();
menus.add(pancakeHouseMenu);
menus.add(dinerMenu);
menus.add(cafeMenu);
Waitress waitress = new Waitress(menus);
waitress.printMenu();
} }

总算是要讲到组合模式了,这个模式可以解决迭代器模式中不能解决的一个难题。比如我们需要一个新的餐单,菜单下又有子菜单,单单用迭代器就不能解决了。这时候可以考虑到用树形结构来展示整个菜单。

看下面的例子吧:

定义菜单组件

package composite;

/**
* 定义菜单组件
* @author Administrator
*
*/
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();
}
}

实现菜单

package composite;

import java.util.ArrayList;
import java.util.Iterator; 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();
}
}
}


实现菜单项

package composite;

/**
* 实现菜单项
* @author Administrator
*
*/
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 boolean isVegetarian() {
return vegetarian;
} public double getPrice() {
return price;
} public void print(){
System.out.print(" " + getName());
if(isVegetarian()) {
System.out.print("(v)");
}
System.out.println("," + getPrice());
System.out.println(" --" + getDescription());
} }

变得十分快乐的女招待

package composite;

import java.util.Iterator;

public class Waitress {
MenuComponent allMenus; public Waitress(MenuComponent allMenus) {
this.allMenus = allMenus;
} public void printMenu() {
allMenus.print();
}
}

我们这样测试

package composite;

import java.util.*;

public class MenuTestDrive {
public static void main(String args[]) {
MenuComponent pancakeHouseMenu =
new Menu("PANCAKE HOUSE MENU", "Breakfast");
MenuComponent dinerMenu =
new Menu("DINER MENU", "Lunch");
MenuComponent cafeMenu =
new Menu("CAFE MENU", "Dinner");
MenuComponent dessertMenu =
new Menu("DESSERT MENU", "Dessert of course!");
MenuComponent coffeeMenu = new Menu("COFFEE MENU", "Stuff to go with your afternoon coffee"); MenuComponent allMenus = new Menu("ALL MENUS", "All menus combined"); allMenus.add(pancakeHouseMenu);
allMenus.add(dinerMenu);
allMenus.add(cafeMenu); pancakeHouseMenu.add(new MenuItem(
"K&B's Pancake Breakfast",
"Pancakes with scrambled eggs, and toast",
true,
2.99));
pancakeHouseMenu.add(new MenuItem(
"Regular Pancake Breakfast",
"Pancakes with fried eggs, sausage",
false,
2.99));
pancakeHouseMenu.add(new MenuItem(
"Blueberry Pancakes",
"Pancakes made with fresh blueberries, and blueberry syrup",
true,
3.49));
pancakeHouseMenu.add(new MenuItem(
"Waffles",
"Waffles, with your choice of blueberries or strawberries",
true,
3.59)); dinerMenu.add(new MenuItem(
"Vegetarian BLT",
"(Fakin') Bacon with lettuce & tomato on whole wheat",
true,
2.99));
dinerMenu.add(new MenuItem(
"BLT",
"Bacon with lettuce & tomato on whole wheat",
false,
2.99));
dinerMenu.add(new MenuItem(
"Soup of the day",
"A bowl of the soup of the day, with a side of potato salad",
false,
3.29));
dinerMenu.add(new MenuItem(
"Hotdog",
"A hot dog, with saurkraut, relish, onions, topped with cheese",
false,
3.05));
dinerMenu.add(new MenuItem(
"Steamed Veggies and Brown Rice",
"Steamed vegetables over brown rice",
true,
3.99)); dinerMenu.add(new MenuItem(
"Pasta",
"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
true,
3.89)); dinerMenu.add(dessertMenu); dessertMenu.add(new MenuItem(
"Apple Pie",
"Apple pie with a flakey crust, topped with vanilla icecream",
true,
1.59)); dessertMenu.add(new MenuItem(
"Cheesecake",
"Creamy New York cheesecake, with a chocolate graham crust",
true,
1.99));
dessertMenu.add(new MenuItem(
"Sorbet",
"A scoop of raspberry and a scoop of lime",
true,
1.89)); cafeMenu.add(new MenuItem(
"Veggie Burger and Air Fries",
"Veggie burger on a whole wheat bun, lettuce, tomato, and fries",
true,
3.99));
cafeMenu.add(new MenuItem(
"Soup of the day",
"A cup of the soup of the day, with a side salad",
false,
3.69));
cafeMenu.add(new MenuItem(
"Burrito",
"A large burrito, with whole pinto beans, salsa, guacamole",
true,
4.29)); cafeMenu.add(coffeeMenu); coffeeMenu.add(new MenuItem(
"Coffee Cake",
"Crumbly cake topped with cinnamon and walnuts",
true,
1.59));
coffeeMenu.add(new MenuItem(
"Bagel",
"Flavors include sesame, poppyseed, cinnamon raisin, pumpkin",
false,
0.69));
coffeeMenu.add(new MenuItem(
"Biscotti",
"Three almond or hazelnut biscotti cookies",
true,
0.89)); Waitress waitress = new Waitress(allMenus); waitress.printMenu();
}
}

测试结果:

ALL MENUS, All menus combined
------------------

PANCAKE HOUSE MENU, Breakfast
------------------
  K&B's Pancake Breakfast(v),2.99
    --Pancakes with scrambled eggs, and toast
  Regular Pancake Breakfast,2.99
    --Pancakes with fried eggs, sausage
  Blueberry Pancakes(v),3.49
    --Pancakes made with fresh blueberries, and blueberry syrup
  Waffles(v),3.59
    --Waffles, with your choice of blueberries or strawberries

DINER MENU, Lunch
------------------
  Vegetarian BLT(v),2.99
    --(Fakin') Bacon with lettuce & tomato on whole wheat
  BLT,2.99
    --Bacon with lettuce & tomato on whole wheat
  Soup of the day,3.29
    --A bowl of the soup of the day, with a side of potato salad
  Hotdog,3.05
    --A hot dog, with saurkraut, relish, onions, topped with cheese
  Steamed Veggies and Brown Rice(v),3.99
    --Steamed vegetables over brown rice
  Pasta(v),3.89
    --Spaghetti with Marinara Sauce, and a slice of sourdough bread

DESSERT MENU, Dessert of course!
------------------
  Apple Pie(v),1.59
    --Apple pie with a flakey crust, topped with vanilla icecream
  Cheesecake(v),1.99
    --Creamy New York cheesecake, with a chocolate graham crust
  Sorbet(v),1.89
    --A scoop of raspberry and a scoop of lime

CAFE MENU, Dinner
------------------
  Veggie Burger and Air Fries(v),3.99
    --Veggie burger on a whole wheat bun, lettuce, tomato, and fries
  Soup of the day,3.69
    --A cup of the soup of the day, with a side salad
  Burrito(v),4.29
    --A large burrito, with whole pinto beans, salsa, guacamole

COFFEE MENU, Stuff to go with your afternoon coffee
------------------
  Coffee Cake(v),1.59
    --Crumbly cake topped with cinnamon and walnuts
  Bagel,0.69
    --Flavors include sesame, poppyseed, cinnamon raisin, pumpkin
  Biscotti(v),0.89
    --Three almond or hazelnut biscotti cookies

上一篇:Python进阶:设计模式之迭代器模式


下一篇:[Usaco2012 Dec]First! BZOJ3012