组合模式
创始人
2024-03-18 16:22:40
0

文章目录

    • 思考组合模式
      • 1.组合模式的本质
      • 2.何时选用组合模式
      • 3.优缺点
      • 4.实现

思考组合模式

组合模式实际上就是让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统一的方式来操作。

1.组合模式的本质

组合模式的本质:统一叶子对象和组合对象。

组合模式通过把叶子对象当成特殊的组合对象看待,从而对叶子对象和组合对象一视同仁,全部当成了Component对象,有机地统一了叶子对象和组合对象。
正是因为统一了叶子对象和组合对象,在将对象构建成树型结构的时候,才不需要做区分,反正是组件对象里面包含其他的组件对象,如此递归下去;也才使得对于树形结构的操作变得简单,不管对象类型,统一操作。
在这里插入图片描述

  • Component:抽象的组件对象,为组合中的对象声明接口,让客户端可以通过这个接口来访问和管理整个对象结构,可以在里面为定义的功能提供缺省的实现。
  • Leaf:叶子节点对象,定义和实现叶子对象的行为,不再包含其他的子节点对象。
  • Composite:组合对象,通常会存储子组件,定义包含子组件的那些组件的行为,并实现在组件接口中定义的与子组件有关的操作。
  • Client:客户端,通过组件接口来操作组合结构里面的组件对象。

2.何时选用组合模式

建议在以下情况中选用组合模式。

  • 如果你想表示对象的部分—整体层次结构,可以选用组合模式,把整体和部分的操作统一起来,使得层次结构实现更简单,从外部来使用这个层次结构也容易。
  • 如果你希望统一地使用组合结构中的所有对象,可以选用组合模式,这正是组合模式提供的主要功能。

3.优缺点

组合模式有以下优点。

  • 定义了包含基本对象和组合对象的类层次结构
    在组合模式中,基本对象可以被组合成复杂的组合对象,而组合对象又可以组合成更复杂的组合对象,可以不断地递归组合下去,从而构成一个统一的组合对象的类层次结构。

  • 统一了组合对象和叶子对象
    在组合模式中,可以把叶子对象当作特殊的组合对象看待,为它们定义统一的父类,从而把组合对象和叶子对象的行为统一起来。

  • 简化了客户端调用
    组合模式通过统一组合对象和叶子对象,使得客户端在使用它们的时候,不需要再去区分它们,客户不关心使用的到底是什么类型的对象,这就大大简化了客户端的使用。

  • 更容易扩展
    由于客户端是统一地面对Component来操作,因此,新定义的Composite或 Leaf子类能够很容易地与已有的结构一起工作,而客户端不需要为增添了新的组件类而改变。

4.实现

一个学校有多个学院,一个学院有多个专业,抽象成一个树形结构
学校和学院都可以有叶子节点,可以共用一个类(Composite),叶子节点单独用一个类(Leaf)
在这里插入图片描述

1.父接口

/*** @description:父接口*/
@Data
public abstract class Component {/*** 打印* @param preStr*/public abstract void print(String preStr);/*** 添加对象* @param component*/public void add(Component component){throw new UnsupportedOperationException("对象不支持这个功能");}/*** 移除对象* @param component*/public void remove(Component component){throw new UnsupportedOperationException("对象不支持这个功能");}}

2.组合对象类

/*** @description:组合对象(学校、学院)*/
public class Composite extends Component {private String name;private List list = new ArrayList<>();public Composite(String name) {this.name = name;}@Overridepublic void print(String preStr) {System.out.println(preStr+"+"+this.name);if (this.list!=null){preStr+=" ";for (Component c: list){c.print(preStr);}}}@Overridepublic void add(Component component) {list.add(component);}@Overridepublic void remove(Component component) {list.remove(component);}}

3.叶子类

/*** @description:叶子对象(系)*/
@AllArgsConstructor
public class Leaf extends Component {/*** 叶子节点名字*/private String name;@Overridepublic void print(String preStr) {System.out.println(preStr+"-"+name);}
}

4.测试类

public class Client {public static void main(String[] args) {//学校Component university = new Composite("清华大学");//学院Component computerCollege = new Composite("计算机学院");Component mathCollege = new Composite("数学学院");//学院添加系computerCollege.add(new Leaf("软件"));computerCollege.add(new Leaf("电子"));computerCollege.add(new Leaf("通信"));mathCollege.add(new Leaf("概率"));mathCollege.add(new Leaf("统计"));//学校添加学院university.add(computerCollege);university.add(mathCollege);//输出学校结构university.print("");}
}

在这里插入图片描述
这样就实现了类似树形结构
在这里插入图片描述

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...