组合模式:允许你将对象组合成树形结构来表现"整体/部分"层次结构,组合能让客户以一致的方式处理个别对象以及对象组合。
例子:菜单有个这样的需求:午餐菜单里面有:炒饭,炒粉,甜品子菜单:布丁、双皮奶。这就涉及到菜单和菜单项,其中炒饭、炒饭是菜单项,甜品子菜单是子菜单。以菜单为例思考,这个模式能够创建一个树形结构,在同一个结构中处理嵌套菜单和菜单项组。通过将菜单和项放在相同的结构中,我们创建了一个"整体/部分"层次结构,即由菜单和菜单项组成的对象树。但是可以将它视为一个整体,像是一个丰富的大菜单。一旦有了这个,我们就可以统一处理个别对象和组合对象。
打印所有菜单:
如果是菜单项目,print()直接打印名称。如果是子菜单,取其迭代器,再遍历调用print()。这样子就可以打印出所有菜单。
组合迭代器:
基于headFirst的菜单例子
/**
利用栈结构,将组合对象的整体(菜单、子菜单)的迭代器放入栈中,用于迭代
*/
public 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;
}
}
/**
判断条件:
1.栈内是否有迭代器
2.迭代器是否已经迭代完
*/
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();
}
}