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,一经查实,立即删除!

相关文章

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

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

第二十一天-NumPy

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

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

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

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

📁 前情提要: Springboot 整合 Elasticsearch(三):使用RestHighLevelClient操作ES ① 目录 一、Springboot 整合 Elasticsearch 1、RestHighLevelClient API介绍 1.1、全查询 & 分页 & 排序 1.2、单条件查询…

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

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

使用cmd命令运行java

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

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

------------★Pygame系列教程★------------ Pygame教程01:初识pygame游戏模块 Pygame教程02:图片的加载缩放旋转显示操作 Pygame教程03:文本显示字体加载transform方法 Pygame教程04: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蓝桥杯每日一题(二分)

一、第一题:教室 解题思路:二分差分 对天数进行二分,在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”工具,来自由管理“npm”的镜像 nrm(npm registry manager)是npm的镜像管理工具,有时候国外的资源太慢,使用这个就可以快速地在npm源间切换。 1.安装nrm 在命令行执行命令,npm install…

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

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

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

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

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

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

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

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

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

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

【JAVA】HashMap扩容性能影响及优化策略

🍎个人博客:个人主页 🏆个人专栏:JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 结语 我的其他博客 前言 在软件开发中,HashMap是一种常用的数据结构,但在处理大量数据时,其扩容…

SpringBoot配置达梦数据库依赖(达梦8)

maven配置 <!-- 达梦数据库 --><dependency><groupId>com.dameng</groupId><artifactId>DmJdbcDriver18</artifactId><version>8.1.1.193</version></dependency><dependency><groupId>com.alibaba&l…

【力扣 - 最大子数组和】

题目描述 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 输出&…

自动化测试过程中的手机验证码处理!

手机验证码登录很普遍了&#xff0c;那么在自动化测试的时候需要登录&#xff0c;登录不了就意味着很多自动化就没法执行下去了。 到底该怎么处理呢&#xff1f;其实并不难&#xff0c;我们先看下验证码的业务逻辑&#xff0c;在我们“点击获取验证码”按钮的时候&#xff0c;…

一学就懂:安装OLED透明屏拼接屏需要注意什么?

安装OLED透明屏拼接屏时&#xff0c;需要注意以下几个方面&#xff1a; 一、前期准备 测量和规划&#xff1a;对安装区域进行详细测量&#xff0c;确保安装区域的尺寸和结构符合OLED透明屏的要求。同时&#xff0c;规划好拼接屏的数量、位置以及布线和固定方案。 环境评估&am…