一、基本介绍
组合模式(结构型):又叫部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。
二、包含角色
1.抽象构件角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。
2.树叶构件角色:是组合中的叶节点对象,它没有子节点,是树枝构件的子节点。
3.树枝构件角色:是组合中的分支节点对象,它有子节点,它的主要作用是存储和管理子部件
三、案例及UML类图
案例说明:
菜单--树枝,菜品—树叶,菜单下有多个菜品,而菜品没有子菜品。要使用户对菜品和菜单的操作都是一致的接口。
UML类图:
类MenuComponent:
public abstract class MenuComponent {
protected String name;
protected String description;
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public void add(MenuComponent menuComponent) {
throw new RuntimeException("不支持该操作!");
}
public void remove(MenuComponent menuComponent) {
throw new RuntimeException("不支持该操作!");
}
public double getPrice() {
throw new RuntimeException("不支持该操作!");
}
public boolean isVegetarian() {
throw new RuntimeException("不支持该操作!");
}
public abstract void print();
}
说明:定义菜单和菜品的操作接口,并显示其默认方法,抽象构建角色。
类MenuItem:
public class MenuItem extends MenuComponent {
private double price;
//是否售完
private boolean egetarian;
public MenuItem(String name,String description,double price, boolean egetarian) {
this.name = name;
this.description = description;
this.price = price;
this.egetarian = egetarian;
}
@Override
public double getPrice() {
return price;
}
@Override
public boolean isVegetarian() {
return egetarian;
}
@Override
public void print() {
System.out.println("名字:"+name+",描述:"+description+",价格:"+price+",已售完:"+egetarian);
}
}
说明:菜品,树叶构件角色,定义菜品的属性和重写菜品自己的方法。
类Menu:
public class Menu extends MenuComponent {
private List<MenuComponent> menuComponents = new ArrayList<>();
public Menu(String name,String description) {
this.name = name;
this.description = description;
}
@Override
public void add(MenuComponent menuComponent) {
menuComponents.add(menuComponent);
}
@Override
public void remove(MenuComponent menuComponent) {
menuComponents.remove(menuComponent);
}
@Override
public void print() {
System.out.println("当前菜单名字是:"+name+",描述是:"+description);
System.out.println("--------------------");
for(MenuComponent menuComponent : menuComponents) {
menuComponent.print();
}
}
}
说明:菜单,树叶构件角色,菜单下包含有菜单或菜品数组,定义菜单自己的属性和重写菜单自己的方法。
类ComponentTest:
public class ComponentTest {
public static void main(String[] args) {
MenuComponent menu = new Menu("精品菜","本店精选!");
MenuComponent menuItem1 = new MenuItem("开水白菜","好吃的白菜",999,false);
menu.add(menuItem1);
menu.print();
}
}
说明:测试及客户端类。
四、适用场景
1.用户需要屏蔽单个对象和组合对象之间的不同,让用户使用同一个接口操作。
2.适用于呈现树叶和树枝结构(树形结构)的业务场景,如文件和文件夹,如XML解析,公司部门等。