9、设计模式之组合模式(Composite)

一、什么是组合模式
组合模式也成为整体部分模式,是一种结构型设计模式。它将对象组合成树形的层次结构,用来表示“整体-部分”的关系。通过组合模式,我们可以使用相同的方式处理单个对象和多个对象组合。

二、角色组成

组件(Component):定义组合模式中所有对象共有的方法和属性。
叶子节点(Leaf):叶子节点对象,也是组合中没有子节点的对象。
组合节点(Composite):表示组合中的容器对象,该对象包含其他子节点。

三、优缺点
优点:

通过组合模式,可以使客户端统一处理单个对象和组合对象,并且不用区分类型,简化了客户端代码的复杂性。
在无需修改现有的代码情况下,可以很容易地增减新的组件类型,更加灵活。
组合对象和单个对象之间的一致性接口可以使代码更易复用
缺点:

可能限制组件的类型:组合模式要求组件和叶子节点具有相同的接口,这可能会限制组件的类型。例如,所有的组件都必须实现相同的操作,即使某些组件并不需要这些操作。
对某些操作的不支持:在组合模式中,对于某些操作,可能只有叶子节点能够支持,而组合对象不能够支持。这可能需要在设计时进行权衡。
可能增加系统复杂性:虽然组合模式可以简化客户端代码,但在另一方面,它也引入了新的类和关系,可能增加了系统的复杂性。在一些简单的情况下,使用组合模式可能会显得过于繁琐。
四、应用场景
4.1 生活场景
古代皇帝:皇帝治理国家不可能具体到某一个人,所以设置了很多机构,比如三省六部,这些机构下面又有很多小的组织,它们共同治理这个国家。
公司:一个公司下面有很多小部门,每个部门下面又分好几个组,有可能再细点每个组又分为职业不同的人(前端、测试、开发、运维)。
文件:比如C盘、D盘下面有很多文件夹,文件夹里面又有很多文件或文件夹。
4.2 java场景

HashMap:putAll()传入的是Map对象,Map就是一个组件,而HashMap就是一个组合节点,HashMap中的Node节点就是叶子节点。同理,ArrayList对象也有addAll()方法。
Java AWT和SWING:对于Button和Checkbox是叶子节点,Container是组合节点。

五、代码实现
下面以算数表达式为例,解释一下组合模式。我们可以把算数表达式看作是一个树状结构,由操作符和操作数组成。

组件(Component):Expression
叶子节点(Leaf):AddOperator、MulOperator、Number
组合节点(Composite):Operator

5.0 UML类图
在这里插入图片描述
5.1 Expression-组件(Component)

/*** * 1.组件(Component):算数表达式*/
public interface Expression {//求值double evaluate();
}

5.2 Number-叶子节点(Leaf)

/*** * 2.叶子节点(Leaf):数字*/
public class Number implements Expression{private double val;public Number(double v){this.val=v;}@Overridepublic double evaluate() {return val;}
}/*** * 2.叶子节点(Leaf):加法操作符*/
public class AddOperator extends Operator{public AddOperator(Expression left, Expression right) {super(left, right);}@Overridepublic double evaluate() {return left.evaluate() + right.evaluate();}
}
/*** * 2.叶子节点(Leaf):加法操作符*/
public class MulOperator extends Operator{public MulOperator(Expression left, Expression right) {super(left, right);}@Overridepublic double evaluate() {return left.evaluate() * right.evaluate();}
}

5.3 Operation-组合节点(Composite)

/*** * 2.组合节点(Composite):运算*/
public abstract class Operator implements Expression{protected Expression left;protected Expression right;public Operator(Expression left, Expression right) {this.left = left;this.right = right;}
//    @Override
//    public double evaluate(){
//        return 0;
//    }
}

5.4 testComposite

/*** * 组合模式测试类*/
@SpringBootTest
public class TestComposite {@Testvoid testComposite(){// 构建一个算数表达式: (2 + 3) * 4Expression expression = new MulOperator(new AddOperator(new Number(2), new Number(3)),new Number(4));// 计算表达式的结果double result = expression.evaluate();System.out.println("(2+3)*4=" + result);}
}

六、总结
组合模式通过把叶子节点当成特殊的组合节点来看待,从而对叶子节点和组合节点能用相同的方式处理,下面总结一下组合模式在程序设计中的使用场景:

对象的层次结构:当你有一组对象,这些对象可以以层次结构的方式进行组织时,组合模式非常有用。例如,文件系统中的文件和文件夹、组织架构中的部门和员工等。
统一处理对象:当你希望能够以统一的方式处理一组对象时,组合模式可以派上用场。组合模式会将叶子对象和组合对象统一对待,这样你就可以通过递归遍历整个对象树,从而对每个对象进行相同的操作。
部分-整体关系:组合模式非常适用于表示部分-整体关系的情况。你可以将单个对象视为整体,将多个对象组合成部分,然后再将多个部分组合成更大的整体,以此类推。
可以忽略对象的具体类型:通过使用组合模式,你可以忽略对象的具体类型,只处理对象的共同接口。这样可以简化代码,使其更加灵活、可扩展和易于维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Centos搭建Nacos集群

一、环境准备 1、安装jdk11https://jdk.java.net/java-se-ri/11 2、下载nacos-server-1.4.1.tar.gz到/home/nacos目录下并解压。在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码: GitHub主页:https…

LightDB24.1 XMLELEMENT支持省略NAME关键字

功能介绍 为了兼容Oracle数据库的语法&#xff0c;LightDB24.1版本开始支持XMLELEMENT函数省略NAME关键字&#xff0c;功能不受影响。 使用示例 带有NAME关键字 lightdboracle_test# SELECT xmlelement(name foo);xmlelement ------------<foo/> (1 row)lightdborac…

ROS机器人程序设计课程进度安排-2023-2024-2

进度安排由人工智能审核制定。 课程 教学进度表预期效果与课程内容详细描述 一、预期效果 此教学进度表旨在确保《ROS机器人程序设计》课程在2023&#xff5e;2024学年度第二学期内&#xff0c;按照预定的教学计划和进度&#xff0c;有序、高效地进行。通过本课程的教学&…

第二十一天-NumPy

目录 什么是NumPy NumPy使用 1.数组的创建 2.类型转换 3.赠删改查 4.数组运算 5.矩阵运算 什么是NumPy 1.NumPy操作的是多维数组&#xff0c;什么是纬度&#xff1f; NumPy使用 1. 安装 pip install numpy import numpy as np 2.官网&#xff1a; 中文官网&#xff1a…

蝙蝠避障:我生活中的一道光

盲人的世界&#xff0c;是无尽的黑暗。看不见光&#xff0c;看不见色彩&#xff0c;甚至看不见自己的手。但在这个黑暗的世界里&#xff0c;我找到了一个光明的出口&#xff1a;一款可以障碍物实时检测的名为蝙蝠避障的盲人软件。 这款软件就像是我的一双眼睛。它通过先进的激光…

HW干货集合 | HW面试题记录(1)

整理最近护网面试问的问题 前言 一开始会问问你在工作中负责的是什么工作&#xff08;如果在职&#xff09;&#xff0c;参与过哪些项目。还有些会问问你之前有没有护网的经历&#xff0c;如果没有的话一般都会被定到初级&#xff08;技术特牛的另说&#xff09;。下面就是一…

Springboot 整合 Elasticsearch(五):使用RestHighLevelClient操作ES ②

&#x1f4c1; 前情提要&#xff1a; Springboot 整合 Elasticsearch&#xff08;三&#xff09;&#xff1a;使用RestHighLevelClient操作ES ① 目录 一、Springboot 整合 Elasticsearch 1、RestHighLevelClient API介绍 1.1、全查询 & 分页 & 排序 1.2、单条件查询…

【linux线程(一)】什么是线程?怎样操作线程?

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; Linux线程 1. 前言2. 什么是线…

使用 Unity 创建 Apple Vision Pro 应用程序和内容的步骤

我们总结了使用 Unity 创建 Apple Vision Pro 应用程序和内容的步骤。 我们总结了使用 visonOS 模拟器检查操作的步骤。 基础知识是按照官方手册进行的,但是有一些部分是我遇到的,所以我附上了很多截图作为备忘录。 参考文章 Unity官方功能页面Unity官方博客Unity官方手册

使用cmd命令运行java

1.普通项目(不带lib文件夹) 1.在桌面上建一个名为com的文件夹&#xff0c;在文件夹中用记事本写两个类文件&#xff0c;后缀改为.java。两个类文件的内容如下图所示&#xff1a; 2.使用javac命令编译主函数&#xff0c;命令行为javac TestMain.java。结果可以看到自动生成了两…

Pygame教程07:键盘常量+键盘事件的2种捕捉方式

------------★Pygame系列教程★------------ Pygame教程01&#xff1a;初识pygame游戏模块 Pygame教程02&#xff1a;图片的加载缩放旋转显示操作 Pygame教程03&#xff1a;文本显示字体加载transform方法 Pygame教程04&#xff1a;draw方法绘制矩形、多边形、圆、椭圆、弧…

理论学习 BatchNorm2d

import torch import torch.nn as nn# With Learnable Parameters m nn.BatchNorm2d(100) # Without Learnable Parameters m nn.BatchNorm2d(100, affineFalse) input torch.randn(20, 100, 35, 45) output m(input)print(output) print(output.shape)这段代码展示了如何使…

2024蓝桥杯每日一题(二分)

一、第一题&#xff1a;教室 解题思路&#xff1a;二分差分 对天数进行二分&#xff0c;在ck函数中用差分方法优化多次区间累加。 【Python程序代码】 n,m map(int,input().split()) a [0] list(map(int,input().split())) d,s,t [0]*(m5),[0]*(m5),[0]*(m5) for…

你还可以通过“nrm”工具,来自由管理“npm”的镜像

你还可以通过“nrm”工具&#xff0c;来自由管理“npm”的镜像 nrm&#xff08;npm registry manager&#xff09;是npm的镜像管理工具&#xff0c;有时候国外的资源太慢&#xff0c;使用这个就可以快速地在npm源间切换。 1.安装nrm 在命令行执行命令&#xff0c;npm install…

Docker容器化技术(数据卷的管理)

数据卷 是一个可供容器使用的特殊目录&#xff0c;它将主机操作系统目录直接 映射进容器&#xff0c;类似于 Linux 中的 mount 行为 。 数据卷&#xff1a;可以提供很多有用的特性 数据卷可以在容器之间共事和重用&#xff0c;容器间传递数据将变得高效与方便&#xff1b;对数…

使用huggingface实现AltCLIP进行对齐语言和图像

目录 引言 使用例子 AltCLIPConfig 参数 示例 AltCLIPTextConfig 参数详解 示例 AltCLIPVisionConfig 参数详解 示例 AltCLIPProcessor 参数 方法 示例使用 AltCLIPModel 前向传播方法 forward 返回值 示例使用 AltCLIPTextModel 方法 forward 返回值 示…

如何选择合适的IP代理,如何为网络爬虫设置代理

目录 前言 1. 代理类型的选择 2. 代理速度 3. 代理稳定性 4. 代理的匿名性 5. 代理的地理位置 总结 前言 在进行网络爬虫任务时&#xff0c;为了避免被目标网站封禁IP或限制访问频率&#xff0c;我们通常会使用代理来隐藏真实的IP地址。选择合适的IP代理对于爬虫的成功…

内部应用解耦神器-Spring事件

大家好&#xff0c;我是程序员牛牛&#xff0c;《AI超级个体: ChatGPT与AIGC实战指南》的参与人&#xff0c;10年Java编程程序员。 1. 概述 在做业务开发过程中&#xff0c;有些复杂点的逻辑&#xff0c;可能代码逻辑会很冗长&#xff0c;举一个很简单的例子&#xff0c;如&am…

【vue.js】文档解读【day 3】 | 条件渲染

如果阅读有疑问的话&#xff0c;欢迎评论或私信&#xff01;&#xff01; 文章目录 条件渲染前言&#xff1a;v-ifv-elsev-else-iftemplate中的v-ifv-showv-if vs v-show 条件渲染 前言&#xff1a; 在JavaScript中&#xff0c;我们知道条件控制语句可以控制程序的走向&#…

Failed to fetch dynamically imported module错误解决方案

工作需要&#xff0c;需要搬移某个功能代码到去年的分支&#xff0c;结果报了这个错 花了2个多小时排查&#xff0c;最后发现&#xff0c;是某个ts文件没有搬过来 吐血&#xff0c;怎么不直接提示这个文件不存在呢&#xff0c;让我研究了半天