1.意图:将对象组合成树型结构以表示”部分-整体“的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
2.结构
Component为组合中的对象声明接口;在适当情况下实现所有类共有接口的默认行为;声明一个接口用于访问和管理Component的子组件;在递归结构中定义一个接口,用于访问一个父组件,并在合适的情况下实现它;
Leaf在组合中表示叶结点对象,叶结点没有子结点;在组合中定义图元对象的行为;
Composite定义有子组件的那些组件的行为;存储子组件;在Component接口中实现与子组件有关的操作;
Client通过Component接口操纵组合组件的对象。
3.适用性:
想标识对象的部分-整体层次结构;
希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
代码案例:
import java.util.ArrayList;
import java.util.List;
/**
* 组合模式
*/
public class Composite {
public static void main(String[] args) {
MenuComponent mainMenu = new Menu("菜单");
MenuComponent subMenu1 = new Menu("1.主食");
MenuComponent element1 = new MenuItem("1.1米饭");
MenuComponent element2 = new MenuItem("1.2面条");
MenuComponent subMenu2 = new Menu("2.配菜");
MenuComponent element3 = new MenuItem("2.1辣椒炒肉");
mainMenu.addMenuElement(subMenu1);
subMenu1.addMenuElement(element1);
subMenu1.addMenuElement(element2);
mainMenu.addMenuElement(subMenu2);
subMenu2.addMenuElement(element3);
printMenus(mainMenu);
}
private static void printMenus(MenuComponent ifile){
ifile.printName();
List<MenuComponent> children = ifile.getElement();
if(children!=null && children.size()>0){
for(MenuComponent element:children){
printMenus(element);
}
}
}
}
abstract class MenuComponent{//构成层叠菜单的元素
protected String name;//菜单项或子菜单名称
public void printName(){
System.out.println(name);
}
public abstract boolean addMenuElement(MenuComponent element);
public abstract boolean removeMenuElement(MenuComponent element);
public abstract List<MenuComponent> getElement();
}
class MenuItem extends MenuComponent{
public MenuItem(String name){
this.name = name;
}
@Override
public boolean addMenuElement(MenuComponent element) {
return false;
}
@Override
public boolean removeMenuElement(MenuComponent element) {
return false;
}
@Override
public List<MenuComponent> getElement() {
return null;
}
}
class Menu extends MenuItem{
private List<MenuComponent> elementList;
public Menu(String name) {
super(name);
this.name = name;
this.elementList = new ArrayList<MenuComponent>();
}
public boolean addMenuElement(MenuComponent element){
return elementList.add(element);
}
public boolean removeMenuElement(MenuComponent element){
return elementList.remove(element);
}
public List<MenuComponent> getElement(){
return elementList;
}
}
运行结果: