一、组合模式
1.组合模式的概述
1.1 组合模式是什么
组合模式是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
三要素:
- 根节点(root):在一棵非空的树中只有一个根节点,这个节点可能有若干个子节点;可以根节点定义系统各层次对象的共有方法和属性。
- 子节点(node):定义子节点的行为,组合子节点和叶子节点形成一个树形结构。
- 叶子节点(leaf):是系统层次遍历的最小单位。
1.2 组合模式应用软件菜单
我们经常在访问管理系统时发现类似下图的菜单一个菜单包含菜单项,也可以包含其他菜单项的菜单。这样使用组合模式描述菜单比较合适,有这样的需求:针对一个菜单打印出其包含所有的菜单以及菜单项的名称。
二、详解组合模式
1.类图表示
2.时序图表示
三、代码实现
抽象类菜单组件MenuComponent定义共有的属性和行为。
/**
* 菜单组件,不管是菜单还是菜单项都是继承这个抽象类
* @author: Husp
* @date: 2023/8/19 13:51
*/
public abstract class MenuComponent {
//菜单名
protected String name;
//菜单层级
protected int level;
/**
* 添加菜单
*/
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(){
return name;
}
/**
* 输出
*/
public void print(){
throw new UnsupportedOperationException();
}
}
定义子菜单Menu覆盖抽象类的属性和行为。
/**
* 菜单有哪些子菜单
* @author: Husp
* @date: 2023/8/19 14:01
*/
public class Menu extends MenuComponent {
//菜单组件集合
private List<MenuComponent> menuComponentList;
public Menu() {
}
//构造函数
public Menu(String name, int level){
this.name=name;
this.level=level;
menuComponentList = new ArrayList<MenuComponent>();
}
//添加菜单
@Override
public void add(MenuComponent menuComponent) {
menuComponentList.add(menuComponent);
}
//删除菜单
@Override
public void remove(MenuComponent menuComponent) {
menuComponentList.remove(menuComponent);
}
//获取子菜单
@Override
public MenuComponent getChild(int i) {
return menuComponentList.get(i);
}
//输出
@Override
public void print() {
for (int i = 0; i < level; i++) {
System.out.print("--");
}
System.out.println(name);
for (MenuComponent menuComponent : menuComponentList) {
menuComponent.print();
}
}
}
定义菜单项MenuItem没有子菜单。
/**
* 菜单项,没有子菜单
* @author: Husp
* @date: 2023/8/19 15:09
*/
public class MenuItem extends MenuComponent{
public MenuItem() {
}
//菜单项构造函数
public MenuItem(String name, int level){
this.name=name;
this.level=level;
}
//输出
@Override
public void print() {
for (int i = 0; i < level; i++) {
System.out.print("--");
}
System.out.println(name);
}
}
测试类
@Test
void test(){
//创建菜单树Menu
MenuComponent menu1 = new Menu("服务审核",2);
menu1.add(new MenuItem("医生详情-待审核",3));
MenuComponent menu2 = new Menu("医生审核",2);
menu2.add(new MenuItem("医生详情-待审核",3));
MenuComponent menu3 = new Menu("用户管理",2);
menu3.add(new MenuItem("家庭档案",3));
menu3.add(new MenuItem("收货地址",3));
//创建一级菜单
MenuComponent component = new Menu("医生管理",1);
//二级菜单添加到一级菜单
component.add(menu1);
component.add(menu2);
component.add(menu3);
//输出菜单
component.print();
}
测试效果: