当前位置:   article > 正文

《JAVA设计模式系列》组合模式_java组合模式

java组合模式

组合模式

组合多个对象形成树形结构以表示“整体-部分”的关系的层次结构。组合模式对叶子节点和容器节点的处理具有一致性,又称为整体-部分模式。

应用场景

部分、整体场景,如树形菜单,文件、文件夹的管理。

组合模式优缺点

优点

  • 高层模块调用简单:组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码。

  • 节点自由增加:更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码。

缺点

  • 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则

  • 设计较复杂,客户端需要花更多时间理清类之间的层次关系。

  • 不容易限制容器中的构件。

组合模式的结构

  • 抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。在透明式的组合模式中抽象构件还声明访问和管理子类的接口;在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。(总的抽象类或接口,定义一些通用的方法,比如新增、删除)。

  • 树枝构件(Composite)角色 / 中间构件:是组合中的分支节点对象,它有子节点,用于继承和实现抽象构件。它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。

  • 树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于继承或实现抽象构件。

实现流程

以一个经典笔试题为例请打印显示文件夹结构的功能, 按如下格式显示

  • 我是根目录

    • 我是二级目录

      • 我是文件

抽象构件(Component)

public abstract class FileComponent {
    //文件名称
    protected String name;
    //文件的层级 1 一级目录 2 二级目录 ...
    protected Integer level;
    //文件的类型 1 文件夹 2文件
    protected Integer type;
    //添加子文件/文件夹
    public abstract void add(FileComponent fileComponent);
    //移除子文件/文件夹
    public abstract void remove(FileComponent fileComponent);
    //获取指定的子文件/文件夹
    public abstract FileComponent getChild(int index);
    //打印子 子文件/子文件夹 名称的方法
    public abstract void print();
}

树枝构件(Composite)

public class FileFolder extends FileComponent{
    //文件夹可以有多个子文件夹或者子文件
    private  List<FileComponent> fileComponentList;
    
    public FileFolder(String name, Integer level, Integer type) {
        this.name = name;
        this.level = level;
        this.type = type;
        this.fileComponentList = new ArrayList<>();
    }
    @Override
    public void add(FileComponent fileComponent) {
        fileComponentList.add(fileComponent);
    }
    @Override
    public void remove(FileComponent fileComponent) {
        fileComponentList.remove(fileComponent);
    }
    @Override
    public FileComponent getChild(int index) {
        return fileComponentList.get(index);
    }
    @Override
    public void print() {
        //打印菜单名称
        for (int i = 0; i < level; i++) {
            System.out.print("\t");
        }
        System.out.println(name);
        //打印子菜单或者子菜单项名称
        for (FileComponent component : fileComponentList) {
            component.print();
        }
    }
}

树叶构件(Leaf)

public class FileItem extends FileComponent{
    public FileItem(String name, Integer level, Integer type) {
        this.name = name;
        this.level = level;
        this.type = type;
    }
    @Override
    public void add(FileComponent fileComponent) {

    }
    @Override
    public void remove(FileComponent fileComponent) {

    }
    @Override
    public FileComponent getChild(int index) {
        return null;
    }
    @Override
    public void print() {
        //打印文件的名称
        for (int i = 0; i < level; i++) {
            System.out.print("\t");
        }
        System.out.println(name);
    }
}

测试

public class Test {
    public static void main(String[] args) {
        //定义根目录
        FileComponent rootComponent = new FileFolder("我是根目录",1,1);
        //定义二级文件夹
        FileComponent secondLevelComponent = new FileFolder("我是二级目录",2,1);
        //定义文件
        FileComponent file = new FileItem("我是文件",3,2);
        //向根目录添加二级目录
        rootComponent.add(secondLevelComponent);
        //向二级目录添加文件
        secondLevelComponent.add(file);
        //打印
        rootComponent.print();
    }
}

输出
在这里插入图片描述

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号