2025年3月31日 星期一 乙巳(蛇)年 正月初一 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 设计模式

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

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

一、描述

首先,看一个数据结构:

在这里插入图片描述

在平时开发过程中,我们的菜单目录、文件夹目录等都有类似如上的实体结构,其中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();
  • }
  • }

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

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