前言
组合模式(Composite Pattern),将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
组合模式主要包含三种角色:
- 抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性;
- 树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构;
- 叶子节点(Leaf):叶子节点对象,其下再无分支,是系统层次遍历的最小单位;
组合方式:
- 透明模式:把组合(树节点)使用的方法放到统一行为(Component)中,让不同层次(树节点,叶子节点)的结构都具备一致行为
- 安全模式:统一行为(Component)只规定系统各个层次的最基础的一致行为,而把组合(树节点)本身的方法(管理子类对象的添加,删除等)放到自身当中;
模式实现
文件抽象节点类
public abstract class AbstractFile {
String name;
public AbstractFile(String name){
this.name = name;
}
/**
* 添加文件
* @param file 文件
*/
public abstract void add(AbstractFile file);
/**
* 删除文件
* @param file 文件
*/
public abstract void remove(AbstractFile file);
/**
* 展示
*/
public abstract void display();
/**
* 树形展示
* @param depth 层级
*/
public abstract void display(int depth);
}
文件类及文件夹类
public class Folder extends AbstractFile {
private final List<AbstractFile> files = new ArrayList<>();
;
public Folder(String name) {
super(name);
}
@Override
public void add(AbstractFile file) {
this.files.add(file);
}
@Override
public void remove(AbstractFile file) {
this.files.remove(file);
}
@Override
public void display() {
for (AbstractFile file : files) {
file.display();
}
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print('-');
}
System.out.println(name);
for (AbstractFile file : files) {
file.display(depth + 1);
}
}
}
public class ImageFile extends AbstractFile{
public ImageFile(String name) {
super(name);
}
@Override
public void add(AbstractFile file) {
throw new UnsupportedOperationException("这个是叶子节点,无法增加");
}
@Override
public void remove(AbstractFile file) {
throw new UnsupportedOperationException("这个是叶子节点,无法删除");
}
@Override
public void display() {
System.out.println(name);
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print('-');
}
System.out.println(name);
}
}
package com.suiyun.combination.demo;
/**
* 文本文件
* @author ww
*/
public class TextFile extends AbstractFile {
public TextFile(String name) {
super(name);
}
@Override
public void add(AbstractFile file) {
throw new UnsupportedOperationException("这个是叶子节点,无法增加");
}
@Override
public void remove(AbstractFile file) {
throw new UnsupportedOperationException("这个是叶子节点,无法删除");
}
@Override
public void display() {
System.out.println(name);
}
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) {
System.out.print('-');
}
System.out.println(name);
}
}
测试类
class CombinationApplicationTests {
@Test
void contextLoads() {
//创建顶级文件夹并添加 test.txt,test.png 以及子文件夹
Folder folder = new Folder("顶级目录文件夹");
folder.add(new TextFile("test.txt"));
folder.add(new ImageFile("test.png"));
Folder subFolder = new Folder("子文件夹");
subFolder.add(new TextFile("subTest.txt"));
folder.add(subFolder);
folder.display(1);
}
}
源码