设计模式-结构型-组合模式

描述

  • 把一组相似的对象,提取到一个单一抽象对象(通过树形结构组合)。
  • 比如文件和文件夹。用户希望的是可以一致操作(都认为是菜单文件)。

角色

  • 抽象根节点:各个层次共有属性和行为。比如文件夹,文件都可以增删等。
  • 树枝节点:可以存储子节点的节点。比如文件夹。
  • 叶子节点:最底层的节点,没有子节点了。比如文件。

分类

  • 透明组合模式:标准模式,在抽象根节点声明了所有用于管理对象的方法。某些方法可能会报错(如例子中的 add,remove方法)。
  • 安全组合模式:在抽象根节点没有声明任何用于管理对象的方法。不够透明,无法抽象编程,需要区分管理树枝节点和叶子节点。

实现(透明组合模式)

  • 把相似的都提取到抽象(菜单文件),(文件和文件夹)实现或继承抽象。可以统一操作抽象。
public class Test {
    public static void main(String[] args) {
        FileSystem fileSystem = new Folder("一级文件系统", 1);

        fileSystem.add(new File("a文件", 2));
        Folder folder = new Folder("二级目录", 2);
        
        folder.add(new Folder("三级目录", 3));
        folder.add(new File("b文件", 3));
        folder.add(new File("c文件", 3));

        fileSystem.add(folder);
        fileSystem.add(new Folder("C目录", 2));

        fileSystem.print();
    }
}

// 抽象根节点:文件系统
abstract class FileSystem {

    protected String name;
    protected Integer level;

    public void add(FileSystem fileSystem) {
        throw new RuntimeException("不可增加子节点");
    }

    public void delete(FileSystem fileSystem) {
        throw new RuntimeException("不可删除子节点");
    }

    public void getChildren() {
        throw new RuntimeException("无字节点可以获取");
    }

    // 打印
    public abstract void print();
}

// 文件夹
class Folder extends FileSystem {

    private final List<FileSystem> fileSystemList = new ArrayList<>();

    Folder(String name, Integer level) {
        super.name = name;
        super.level = level;
    }

    @Override
    public void add(FileSystem fileSystem) {
        fileSystemList.add(fileSystem);
    }

    @Override
    public void delete(FileSystem fileSystem) {
        fileSystemList.remove(fileSystem);
    }

    @Override
    public void getChildren() {
        System.out.println(Arrays.toString(fileSystemList.toArray()));
    }

    @Override
    public void print() {
        StringBuilder space = new StringBuilder();
        for (int i = 0; i < level; i++) {
            space.append("\t");
        }
        space.append(name);
        System.out.println(space);

        fileSystemList.forEach(FileSystem::print);
    }
}

// 文件
class File extends FileSystem {

    File(String name, Integer level) {
        super.name = name;
        super.level = level;
    }

    @Override
    public void print() {
        StringBuilder space = new StringBuilder();
        for (int i = 0; i < level; i++) {
            space.append("\t");
        }
        space.append(name);
        System.out.println(space);
    }
}

优点

  • 组合模式可以清晰的表达各个层级的节点,忽略层次差异。
  • 客户端可以一致操作抽象节点
  • 新增树枝节点或根节点,不需要修改原有结构,符合开闭原则。
  • 树形结构解决方案。

使用场景

  • 处理树形结构的数据时,可以使用组合模式。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值