package K_Composite;
import java.util.Iterator;
import java.util.Stack;
/**
-
组合迭代器
-
外部迭代器,所以需要维护组合递归结构的位置,采用栈维护
*/
public class CompositeIterator implements Iterator {
Stack stack = new Stack();public CompositeIterator(Iterator iterator) {
stack.push(iterator);
}public boolean hasNext() {
if (stack.empty()) {
return false;
} else {
Iterator peek = stack.peek();
if (!peek.hasNext()) {
stack.pop();
return hasNext();
} else
return true;
}
}public Object next() {
if (hasNext()) {
Iterator peek = stack.peek();
MenuComponent next = (MenuComponent) peek.next();
if (next instanceof Menu) {
stack.push(next.createIterator());
}
return next;
}
return null;
}public void remove() {
throw new UnsupportedOperationException();
}
}
package K_Composite;
/**
-
组合模式:允许你将对象组合成树形结构来表现"整体/部分"层次结构。组合能让客户以一致的方式处理个别对象以及对象组合
-
尽管组合内的对象行为不一样,但是为了保持透明性,以及让用户不操心那个对象用那个接口,需要实现同一接口
-
用不同的接口组合,也算组合模式(更加安全的组合模式)
*/
public class Main {
public static void main(String[] args) {
MenuComponent pancakeHouseMenu = new Menu(“煎饼菜单”, “早餐”);
MenuComponent dinermenu = new Menu(“早餐”, “早餐”);
MenuComponent cafeMenu = new Menu(“午餐”, “午餐”);
MenuComponent dessertMenu = new Menu(“甜点”, “甜点”);MenuComponent allMenu = new Menu("所有菜单", "all menu"); allMenu.add(pancakeHouseMenu); allMenu.add(dinermenu); allMenu.add(cafeMenu); dinermenu.add(new MenuItem("拉面", "拉面", true, 10)); dinermenu.add(dessertMenu); dessertMenu.add(new MenuItem("南瓜饼", "南瓜饼", false, 10)); Waitress waitress = new Waitress(allMenu); waitress.printMenu();
}
}
package K_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 component) {
menuComponents.add(component);
}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;
}/*
因为菜单是一个组合,包含菜单项和其他菜单,所以print应该打印它所包含的一切。
内部迭代器
*/
public void print() {
System.out.println(getName() + " " + getDescription());
Iterator iterator = menuComponents.iterator();
while (iterator.hasNext()) {
MenuComponent menu = (MenuComponent) iterator.next();
menu.print();
}
}/*
外部迭代器,所以需要维护组合递归结构的位置,采用栈维护
*/
@Override
public Iterator createIterator() {
return new CompositeIterator(menuComponents.iterator());
}
}
package K_Composite;
import java.util.Iterator;
//提供默认实现,所以使用抽象类
public abstract class MenuComponent {
/*
* 组合方法
*/
public void add(MenuComponent component) {
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 abstract Iterator createIterator();
}
package K_Composite;
import java.util.Iterator;
/**
*菜单项(叶子节点)
*菜单项如何实现createIterator
*方案1:直接返回null,这样做后客户代码需要每次判断这个方法是否返回的null
*方案2:返回迭代器,hasNext()永远返回false
*/
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.println(toString());
}
@Override
public String toString() {
return "MenuItem [name=" + name + ", description=" + description
+ ", vegetarian=" + vegetarian + ", price=" + price + "]";
}
@Override
public Iterator createIterator() {
return new NullIterator();
}
}
package K_Composite;
import java.util.Iterator;
public class NullIterator implements Iterator {
@Override
public boolean hasNext() {
return false;
}
@Override
public Object next() {
return null;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
package K_Composite;
import java.util.Iterator;
public class Waitress {
MenuComponent allMenus;
public Waitress(MenuComponent allMenus) {
this.allMenus = allMenus;
}
public void printMenu() {
allMenus.print();
}
public void printVegetarianMenu() {
Iterator createIterator = allMenus.createIterator();
System.out.println("打印素食菜单");
while (createIterator.hasNext()) {
MenuComponent next = (MenuComponent) createIterator.next();
try {
if (next.isVegetarian()) {
next.print();
}
//只在菜单上实现了isVegetarian,菜单项调用时候会抛出此异常
//也可以在菜单项实现isVegetarian(),返回false,但是跟不支持查看素食意义不一样,推荐这种
} catch (UnsupportedOperationException e) {
}
}
}
}