概述
组合模式 : Composite Pattern : 是一种结构型设计模式。
**它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。**
核心思想:
让单个对象 和 组合对象 实现相同的接口,这样就可以在不区分是单个对象还是组合对象的情况下,以相同的方式处理它们。
这极大地简化了客户端代码,并且能够构建出复杂的层次结构。
使用场景:
实际上,当需要用到 树形结构的时候,就可以使用此模式。
例如 : 文件的目录结构,有文件夹和文件 两个类型,文件夹包含文件列表,这就可以是一个树形的结构。
核心组件
Component(组件):这是组合中的抽象基类或接口,声明了所有共有方法,包括操作自身的方法以及操作子部件的方法。
Leaf(叶子节点): 表示没有子部件的组件
。Leaf 类实现了 Component 中定义的所有操作,通常情况下 Leaf 不会实现任何操 作子部件的方法,因为它没有子部件。
Composite(组合): 代表包含子部件的组件
。Composite 类不仅实现了 Component 中定义的操作,还维护了一个子部件的列表,并实现了相关的管理子部件的方法,如添加、删除或访问子部件等。
案例
案例描述
文件系统中,有 文件夹 和 文件两种类型。
文件夹中包含文件,有 添加、删除、展示文件列表的功能,这就是一个 【Composite 组合对象】;
文件就是 一个叶子节点【Leaf节点】。
类图
案例代码
接口
public interface FileSystemComponent {
// 添加节点,仅 文件夹有具体实现
void add(FileSystemComponent component);
// 删除节点,仅 文件夹有具体实现
void remove(FileSystemComponent component);
// 显示节点,
void display();
}
文件类
public class FileLeaf implements FileSystemComponent {
private String name;
// 常规的 构造方法、getter、setter,不再赘述
@Override
public void add(FileSystemComponent component) {
System.out.println("文件节点,不支持添加下一个节点!");
}
@Override
public void remove(FileSystemComponent component) {
System.out.println("文件节点,不支持移除对应的节点!");
}
@Override
public void display() {
System.out.println("文件 : "+ name);
}
}
文件夹类
public class FloderComposite implements FileSystemComponent{
private String name;
// 这个就是自包含的类型
private List<FileSystemComponent> fileList;
// 常规的 构造方法、getter、setter,不再赘述
@Override
public void add(FileSystemComponent component) {
if (fileList == null || fileList.isEmpty()){
fileList = new ArrayList<>();
}
fileList.add(component);
System.out.println("文件夹 "+name+" 添加文件成功!\n");
}
@Override
public void remove(FileSystemComponent component) {
if (fileList != null && !fileList.isEmpty()){
fileList.remove(component);
}
System.out.println("文件夹 "+name+" 移除文件成功!\n");
}
@Override
public void display() {
// todo 实际上,此处是个递归操作
System.out.println("文件夹 "+name+" 展示 begin-----");
if (fileList != null && !fileList.isEmpty()){
for (FileSystemComponent fileSystemComponent : fileList) {
fileSystemComponent.display();
}
}
System.out.println("文件夹 "+name+" 展示 end----- \n");
}
}
使用案例
public class CompositeTest {
/**
* 目录结构如下
* | -- root
* | -- floder1
* | -- file1
* | -- floder2
* | -- file2
*/
public static void main(String[] args) {
// 创建两个文件对象
FileLeaf file1 = new FileLeaf("file1");
FileLeaf file2 = new FileLeaf("file2");
// 创建两个文件夹对象
FloderComposite floder1 = new FloderComposite("floder1");
FloderComposite floder2 = new FloderComposite("floder2");
// 创建一个根目录文件夹对象
FloderComposite root = new FloderComposite("root");
// 将文件/文件夹 对象添加到 根目录对象中
floder1.add(file1);
floder2.add(file2);
root.add(floder1);
root.add(floder2);
// 展示一下文件夹中的内容
root.display();
}
}
运行结果:
文件夹 floder1 添加文件成功!
文件夹 floder2 添加文件成功!
文件夹 root 添加文件成功!
文件夹 root 添加文件成功!
文件夹 root 展示 begin-----
文件夹 floder1 展示 begin-----
文件 : file1
文件夹 floder1 展示 end-----
文件夹 floder2 展示 begin-----
文件 : file2
文件夹 floder2 展示 end-----
文件夹 root 展示 end-----