Appearance
组合设计模式又叫部分整体模式,将对象组合成树形结构以表示“部分-整体”的层次结构,可以更好的实现管理操作,组合模式使得用户可以使用一致的方法操作单个对象和组合对象。
组合模式使得用户可以使用一致的方法操作单个对象和组合对象。部分-整体对象的基本操作多数是一样的,但是应该还会有不一样的地方。核心:组合模式可以使用一棵树来表示
应用场景
- 银行总行,总行有前台、后勤、网络部门等,辖区下还有地方分行,也有前台、后勤、网络部门,最小的分行就没有子分行了
- 公司也是,总公司下有子公司,每个公司大部分的部门都类似
- 文件夹和文件,都有增加、删除等api,也有层级管理关系
- 当想表达对象的部分-整体的层次结构
- 当我们的要处理的对象可以生成一颗树形结构,我们要对树上的节点和叶子进行操作时,它能够提供一致的方式,而不用考虑它是节点还是叶子
角色
- 组合部件(Component):它是一个抽象接口,表示树根,例子:总行
- 合成部件(Composite):和组合部件类似,也有自己的子节点,例子:总行下的分行
- 叶子(Leaf):在组合中表示子节点对象,注意是没有子节点,例子:最小地方的分行
编码实现
场景:windows系统文件系统
创建根节点
java
/**
* 根节点,抽象类,通用的属性和方法
* @author cv大魔王
* @version 1.0
* @date 2021/7/12 21:44
*/
public abstract class Root {
// 文件名
private String name;
public Root(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 添加文件
public abstract void addFile(Root root);
// 删除文件
public abstract void removeFile(Root root);
// 递归展示文件
public abstract void display(int depth);
}
创建文件夹
java
/**
* 文件夹,里面可添加子文件或子文件夹
* @author cv大魔王
* @version 1.0
* @date 2021/7/12 21:47
*/
public class Folder extends Root {
List<Root> folders = new ArrayList<>();
public Folder(String name) {
super(name);
}
public List<Root> getFolders() {
return folders;
}
public void setFolders(List<Root> folders) {
this.folders = folders;
}
@Override
public void addFile(Root root) {
folders.add(root);
}
@Override
public void removeFile(Root root) {
folders.remove(root);
}
@Override
public void display(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
// 打印横线和当前文件名
System.out.println(new String(sb) + this.getName());
// 递归
for (Root r : folders) {
// 每个下级,横线多两个
r.display(depth + 2);
}
}
}
文件
java
/**
* 这个类没有子节点,不需要存储其他子类数组
* @author cv大魔王
* @version 1.0
* @date 2021/7/12 21:53
*/
public class MyFile extends Root{
public MyFile(String name) {
super(name);
}
@Override
public void addFile(Root root) {
}
@Override
public void removeFile(Root root) {
}
@Override
public void display(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
// 打印横线和当前文件名
System.out.println(new String(sb) + this.getName());
}
}
使用
java
public static void main(String[] args) {
// 创建根文件夹
Root root = new Folder("c://");
// 创建子文件夹
Root desktop = new Folder("桌面");
Root myComputer = new Folder("我的电脑");
// 创建子文件
Root javaFile = new MyFile("hello.java");
// 建立关系
root.addFile(desktop);
root.addFile(myComputer);
myComputer.addFile(javaFile);
// 从0级开始展示,每下一级,多两条横线
root.display(0);
}