允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
创建一个树形结构,在同一个结构中处理嵌套菜单和菜单项组。通过将菜单和项放在相同的结构中,我们创建了一个“整体/部分”层次结构,即使由 菜单 和 菜单 项 组成 的 对象 树 。但是 可以 将 他视为 一个 整体,像是 一个 丰富的大菜单 。
1.我们应该努力让一个类只分配一个责任。
2.组合模式提供了一种结构,可同时包容个别对象和组合对象。
3。组合模式允许客户对个别对象和组合对象一视同仁。
4.组合结构内的任意对象称为组件,组件可以是组合,也可以是叶子节点。
5.在实现组合模式时,有许多设计上的 折中。你要根据需要平衡透明性和安全性。
package pattern;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Stack;
public class MenuTestDrive2 {
public static void main(String[] args) {
MenuComponent pancakeHouseMenu = new Menu("PANCAKE HOUSE MENU","Breakfast");
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,and sausage", true, 2.99));
pancakeHouseMenu.add(new MenuItem("BlueBerry Pancakes ", "Pancakes made with fresh blueberries",
true, 3.49));
pancakeHouseMenu.add(new MenuItem("Waffles",
"Waffles with your choice of blueberries or strawberries",
true, 3.59));
MenuComponent dinerMenu = new Menu("DINER MENU","Lunch");
MenuComponent cafeMenu = new Menu("CAFE MENU","dINNER");
MenuComponent dessertMenu = new Menu("DESSERT MENU","Dessert of course!");
MenuComponent allMenus=new Menu("ALL MENUS","ALL menus combined");
allMenus.add(pancakeHouseMenu);
allMenus.add(dinerMenu);
allMenus.add(cafeMenu);
cafeMenu.add(new MenuItem("Vegegie Burger and Air Fries",
"Veggie burger on a whole wheat bun,lettuce,tomato,and fries", true,
3.99));
dinerMenu.add(new MenuItem("Soup of the day", "A cup of the soup of the day,with a side salad", true,
2.99));
dinerMenu.add(new MenuItem("Burrito",
"A large burrito , with whole pinto beans,salsa,guacamole", true, 2.99));
dinerMenu.add(new MenuItem("Hotdog",
"A hot dog, with saurkraut,relish,onions,topped with cheese",
true, 2.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 ice cream",true,1.59));
Waiter waitress = new Waiter(allMenus);
waitress.printMenu();
}
}
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(){}
public Iterator createIterator(){
throw new UnsupportedOperationException();
}
}
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(this.isVegetarian()){
System.out.println("(v)");
}
System.out.println(","+getPrice());
System.out.println(" ---"+getDescription());
}
public Iterator createIterator(){
return new NullIterator();
}
}
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 =(Iterator)menuComponents.iterator();
while(iterator.hasNext()){
MenuComponent menuComponent=(MenuComponent)iterator.next();
menuComponent.print();
}
}
public Iterator createIterator(){
return new CompositeIterator(menuComponents.iterator());
}
}
class CompositeIterator implements Iterator{
Stack stack=new Stack();
public CompositeIterator(Iterator iterator){
stack.push(iterator);
}
public Object next(){
if(hasNext()){
Iterator iterator=(Iterator)stack.peek();
MenuComponent component=(MenuComponent)iterator.next();
if(component instanceof Menu){
stack.push(component.createIterator());
}
return component;
}else{
return null;
}
}
public boolean hasNext(){
if(stack.empty()){
return false;
}else{
Iterator iterator =(Iterator)stack.peek();
if(!iterator.hasNext()){
stack.pop();
return hasNext();
}else{
return true;
}
}
}
public void remove(){
throw new UnsupportedOperationException();
}
}
class NullIterator implements Iterator{
public Object next(){
return null;
}
public boolean hasNext(){
return false;
}
public void remove(){
throw new UnsupportedOperationException();
}
}
class Waiter {
MenuComponent allMenus;
public Waiter(MenuComponent allMenus){
this.allMenus=allMenus;
}
public void printMenu() {
this.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){}
}
}
}