组合模式:把类似对象或方法组合成结构为树状的设计思路。
例如部门之间的关系。
设计模式,一定要敲代码理解
抽象组件
/**
* @author ggbond
* @date 2024年04月06日 08:54
* 部门有:二级部门(下面管三级部门) 三级部门 (无子部门)
*/
public abstract class Compound {
private String name; // 部门
public Compound(String name) {
this.name = name;
}
public String getName() {
return name;
}
public abstract void add(Compound component); // 添加子部门
public abstract void remove(Compound component); // 删除子部门
public abstract void select(int depth); // 查看全部子部门
}
叶子结点
/**
* @author ggbond
* @date 2024年04月06日 08:57
* 叶子节点 三级部门
*/
public class Leaf extends Compound {
public Leaf(String name) {
super(name);
}
@Override
public void add(Compound component) {
System.out.println("不能加子部门");
}
@Override
public void remove(Compound component) {
System.out.println("无子部门,无删除权限");
}
@Override
public void select(int depth) {
//输出树形结构的叶子节点,这里直接输出设备名称
for(int i = 0; i < depth; i++) {
System.out.print("*");
}
System.out.print(" ");
System.out.println(getName());
}
}
非叶子结点
/**
* @author ggbond
* @date 2024年04月06日 09:00
*/
public class Composite extends Leaf{
// 记录子部门信息
private ArrayList<Compound> list = new ArrayList<>();
public Composite(String name) {
super(name);
}
@Override
public void add(Compound component) {
list.add(component);
}
@Override
public void remove(Compound component) {
list.remove(component);
}
@Override
public void select(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print("*");
}
System.out.print(" ");
System.out.println(getName());
// 递归
for(Compound compound: list) {
compound.select(depth + 1);
}
}
}
测试结果
/**
* @author ggbond
* @date 2024年04月06日 09:04
*/
public class Main {
public static void main(String[] args) {
Composite root=new Composite("一级部门1");
//二级部门1
Composite r21=new Composite("二级部门1");
r21.add(new Composite("三级部门1"));
r21.add(new Composite("三级部门2"));
r21.add(new Composite("三级部门3"));
//二级部门2
Composite r22=new Composite("二级部门2");
r22.add(new Composite("三级部门4"));
r22.add(new Composite("三级部门5"));
r22.add(new Composite("三级部门6"));
//二级部门3
Composite r23=new Composite("二级部门3");
root.add(r21); root.add(r22); root.add(r23);
root.select(1);
}
}
* 一级部门1
** 二级部门1
*** 三级部门1
*** 三级部门2
*** 三级部门3
** 二级部门2
*** 三级部门4
*** 三级部门5
*** 三级部门6
** 二级部门3
总结
满足开闭原则。叶子结点与非叶子结点都继承或实现同一抽象,只是叶子功能权限少,而非叶子结点需要容器记录子节点。
代码下载
代码下载