组合模式:允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象(叶子节点)以及对象组合。
也就是我们能把相同的操作应用在组合和个别对象上,忽略对象组合和个别对象差异。这实现了透明性,虽然违背了单一责任设计原则。
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 boolean isVegetarian(){
throw new UnsupportedOperationException();
}
public void print(){
throw new UnsupportedOperationException();
}
}
public class MenuItem extends MenuComponent {
String name;
boolean vagetarian;
public MenuItem(String name,boolean vegetaration){
this.name = name;
this.vagetarian = vegetaration;
}
public String getName() {
return name;
}
public boolean isVegetaration() {
return vagetarian;
}
public void print(){
getName();
}
}
public class Menu extends MenuComponent{
ArrayList<MenuComponent> menuComponents = new ArrayList();
String name;
public Iterator createIterator(){
return menuComponents.iterator();
}
public void add(MenuComponent menuComponent){
}
public void remove(MenuComponent menuComponent){
}
public MenuComponent getChild(int i){
return menuComponents.get(i);
}
public String getName(){
return name;
}
public void print(){
Iterator iterator = menuComponents.iterator();//这是一个内部迭代器,DFS
while (iterator.hasNext());
}
}
public class CompositeIterator implements Iterator {
Stack<Iterator> stack = new Stack<>();
public CompositeIterator(Iterator iterator){
stack.push(iterator);
}
@Override
public boolean hasNext() {
if (stack.empty()) return false;
Iterator iterator = (Iterator) stack.peek();
if (!iterator.hasNext()){
stack.pop();//去掉栈里没有后续元素的递归调用hasNext()
return hasNext();
}
return true;
}
@Override
public Object next() {
if (hasNext()){
Iterator iterator = (Iterator) stack.peek();
MenuComponent menuComponent = (MenuComponent) iterator.next();
if (menuComponent instanceof Menu) stack.push(((Menu) menuComponent).createIterator());
return menuComponent;
}
else return null;
}
}
public class Waitress {
MenuComponent allMenus;
public Waitress(MenuComponent menuComponent){
allMenus = menuComponent;
}
public void printMenu(){
allMenus.print();
}
}