您当前的位置:首页 > 计算机 > 编程开发 > 设计模式

【设计模式】32.结构型模式-组合模式(Composite)

时间:02-01来源:作者:点击数:

一、描述

首先,看一个数据结构:

在这里插入图片描述

在平时开发过程中,我们的菜单目录、文件夹目录等都有类似如上的实体结构,其中composite代表父级节点,leaf代表叶子节点,composite可以有子节点,但是leaf下没有节点。解析此结构时,循环解析每个节点,当解析到叶子节点时,当前循环结束。这种数据结构就是组合模式的代表结构。

定义:

组合模式将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性。

角色

(1)Component(抽象构件):为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。定义了管理子构件的方法,如定义了新增构件、删除构件、获取构件的方法等。

(2)Composite(中间构件):提供一个集合包含其他构件或者叶子节点,实现抽象构件方法,管理集合中的节点。

(3)Leaf(叶子节点):实现抽象构件方法,但是其没有子节点。

类图

在这里插入图片描述

二、优点

(1)高层模块调用简单。一颗树形结构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,高层模块不必关心自己处理的是单个对象还是整个组合接口。

(2)节点自由添加

三、缺点

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

四、使用场景

(1)维护和展示部分-整体关系的场景(树形菜单、文件和文件夹管理)

(2)一个整体中能够独立出部分模块或功能的场景

五、示例

以“电脑硬盘上的文件夹以及文件为例”,文件夹下有文件,文件夹是具体构件,文件是叶子节点。下面是代码:

(1)IFile,定义文件公共方法

public interface IFile {
    /**
     * 添加文件或者文件夹
     *
     * @param iFile
     */
    void add(IFile iFile);

    /**
     * 删除文件或者文件夹
     *
     * @param iFile
     */
    void delete(IFile iFile);

    /**
     * 获取文件或者文件夹
     *
     * @return
     */
    void operation();

    /**
     * 获取文件信息
     *
     * @param i
     * @return
     */
    IFile get(int i);
}

(2)定义中间构件Folder

public class Folder implements IFile {
    //存储文件集合
    private List<IFile> children = new ArrayList<>();
    //文件夹名称
    private String name;

    public Folder(String name) {
        this.name = name;
    }

    @Override
    public void add(IFile iFile) {
        children.add(iFile);
    }

    @Override
    public void delete(IFile iFile) {
        children.remove(iFile);
    }

    @Override
    public void operation() {
        System.out.println(name + "文件夹,其下有:");
        for (int i = 0; i < children.size(); i++) {
            System.out.print("-");
            children.get(i).operation();
        }
    }

    @Override
    public IFile get(int i) {
        return children.get(i);
    }
}

(3)叶子节点File,文件

public class File implements IFile {
    private String name;

    public File(String name) {
        this.name = name;
    }

    @Override
    public void add(IFile iFile) {
        System.out.println("叶子节点无法添加文件");
    }

    @Override
    public void delete(IFile iFile) {
        System.out.println("叶子节点无法删除文件");
    }

    @Override
    public void operation() {
        System.out.println(name + "文件");
    }

    @Override
    public IFile get(int i) {
        return this;
    }
}

(4)Client,客户端

文件夹结构如下:

d:
-code:
--company:
---projectA:
----classA1
---projectB
----classB1
-me
--myproject:
---excelA.xls
public class Client {
    public static void main(String[] args) {
        //D盘下有code文件夹,code文件夹下有company和me文件夹,文件夹下是项目,项目下是代码文件
        Folder d = new Folder("d盘");
        Folder code = new Folder("code");
        Folder company = new Folder("company");
        Folder me = new Folder("me");

        d.add(code);
        code.add(company);
        code.add(me);

        Folder projectA = new Folder("projectA");
        File classA1 = new File("classA1");
        projectA.add(classA1);
        Folder projectB = new Folder("projectB");
        File classB1 = new File("classB1");
        projectB.add(classB1);
        company.add(projectA);
        company.add(projectB);

        Folder myProject = new Folder("myProject");
        File excelA = new File("excelA.xls");
        me.add(myProject);
        me.add(excelA);

        d.operation();
    }
}

实现效果,由于主要是体现组合模式,因此没有实现结构划分:

在这里插入图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门