组合模式(Composite)
意图
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
动机
组合模式通过一种巧妙的设计方案使得用户可以一致性地处理整个树形结构或者树形结构的一部分,它描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器对象和叶子对象。
结构
何时使用
当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。
实现
/**
* 场景:实现一个菜单树
*/
//第一步:创建一个菜单组件(Component)
package com.wlj.composite;
/**
* @author wlj
* @Classname MenuComponent
* @Description 菜单组件,无论是菜单还是菜单项,都继承该类
* @Date 6/15/2022 4:27 PM
*/
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();
}
}
//第二步:子菜单项(树枝节点)
package com.wlj.composite;
import java.util.ArrayList;
import java.util.List;
/**
* @author wlj
* @Classname Menu
* @Description 子菜单项
* @Date 6/15/2022 4:33 PM
*/
public class Menu extends MenuComponent{
private List<MenuComponent> menuComponentList;
public Menu(String name,int level){
this.level = level;
this.name = name;
menuComponentList = new ArrayList<MenuComponent>();
}
/**
* 添加菜单
*
* @param menuComponent
*/
@Override
public void add(MenuComponent menuComponent) {
menuComponentList.add(menuComponent);
}
/**
* 移除菜单
*
* @param menuComponent
*/
@Override
public void remove(MenuComponent menuComponent) {
menuComponentList.remove(menuComponent);
}
/**
* 获取指定的子菜单
*
* @param i
*/
@Override
public MenuComponent getChild(int i) {
return menuComponentList.get(i);
}
@Override
public void print() {
// 方便打印出层级效果
for (int i = 1; i < level; i++) {
System.out.print("--");
}
System.out.println(name);
//递归打印
for (MenuComponent menuComponent : menuComponentList) {
menuComponent.print();
}
}
}
//第三步:叶子节点
package com.wlj.composite;
/**
* @author wlj
* @Classname MenuItem
* @Description 叶子节点,不存在子节点
* @Date 6/15/2022 4:40 PM
*/
public class MenuItem extends MenuComponent{
public MenuItem(String name,int level) {
this.name = name;
this.level = level;
}
@Override
public void print() {
// 方便打印出层级效果
for (int i = 1; i < level; i++) {
System.out.print("--");
}
System.out.println(name);
}
}
//Client测试类
public class Client {
public static void main(String[] args) {
//一级菜单
MenuComponent root = new Menu("系统管理",1);
//二级菜单
MenuComponent authority = new Menu("权限管理",2);
//二级菜单
MenuComponent role = new Menu("角色管理",2);
//权限管理三级菜单
authority.add(new MenuItem("查看权限",3));
authority.add(new MenuItem("修改权限",3));
//角色管理三级菜单
role.add(new MenuItem("删除角色",3));
root.add(authority);
root.add(role);
//打印
root.print();
}
}
//结果
系统管理
--权限管理
----查看权限
----修改权限
--角色管理
----删除角色