概念
又名部分整体模式,是用于把一组相似的对象当做一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层级
结构
抽象根节点:定义系统中各个层次对象的共有方法、属性,可以预先定义一些默认行为和属性
树状节点:定义树枝节点的行为,存储子节点,组合树枝节点、叶子节点形成一个树形结构
叶子节点:是系统层级遍历的最小单位,其下再无分支
示例
目标:构建一个文件系统,文件夹下存储文件夹、文件
抽象根节点
import lombok.Getter;
/**
* 堆代码 duidaima.com
* 文件系统组件:抽象根节点
*/
@Getter
public abstract class FileSystemComponent {
/** 名称 */
protected String name;
/** 层级 */
protected int level = 0;
/**
* 增加一个子级组件
*/
void add(FileSystemComponent component) {
throw new UnsupportedOperationException();
}
/**
* 删除一个子级组件
*/
void remove(FileSystemComponent component) {
throw new UnsupportedOperationException();
}
/**
* 打印自身、所有子级的名称
*/
abstract void print();
}
树状节点
import java.util.ArrayList;
import java.util.List;
/**
* 目录:树枝节点
*/
public class Dir extends FileSystemComponent {
/** 子级组件 */
List<FileSystemComponent> sonList = new ArrayList<>();
/**
* 构造方法
*/
Dir(String name) {
this.name = name;
}
/**
* 增加一个子级组件
*/
void add(FileSystemComponent component) {
// 层级+1
component.level = getLevel() + 1;
// 添加数据
sonList.add(component);
}
/**
* 删除一个子级组件
*/
void remove(FileSystemComponent component) {
sonList.remove(component);
}
@Override
void print() {
// 打印当前
for (int i = 0; i < getLevel(); i++) {
System.out.print(" ");
}
System.out.println(getName());
// 打印子级
for (FileSystemComponent component : sonList) {
component.print();
}
}
}
叶子节点
/**
* 目录:叶子节点
*/
public class File extends FileSystemComponent {
/**
* 构造方法
*/
File(String name) {
this.name = name;
}
@Override
void print() {
for (int i = 0; i < getLevel(); i++) {
System.out.print(" ");
}
System.out.println(getName());
}
}
测试类
public class Demo {
public static void main(String[] args) {
// 根目录
Dir root = new Dir("个人学习资料库");
// 堆代码 duidaima.com
// 一层目录
Dir first_front = new Dir("前端");
Dir first_background = new Dir("后台");
// 将一层目录加入根目录中
root.add(first_front);
root.add(first_background);
// 二层目录、文件
Dir second_front_css = new Dir("CSS");
Dir second_front_typeScript = new Dir("TypeScript");
File second_background_mybatis = new File("Mybatis.docx");
Dir second_background_spring = new Dir("Spring大全");
// 将二层目录、文件加入一层目录中
first_front.add(second_front_css);
first_front.add(second_front_typeScript);
first_background.add(second_background_mybatis);
first_background.add(second_background_spring);
// 打印根目录结构
root.print();
}
}
优缺点
优点
1.组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便了对整体层次结构进行控制
2.客户端可以一致的使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码
3.新增树状节点、叶子节点时符合开闭原则,不必对现有代码进行任何修改
应用场景
需要用到树状结构的地方都可以使用组合模式