当前位置: 首页 > news >正文

研磨设计模式day13组合模式

目录

场景

不用模式实现 

代码实现 

有何问题 

解决方案

代码改造 

组合模式优缺点

思考 

何时选用


场景

不用模式实现 

代码实现 

叶子对象

package day14组合模式;/*** 叶子对象*/
public class Leaf {/*** 叶子对象的名字*/private String name = "";/*** 构造方法,传入叶子对象的名字*/public Leaf(String name){this.name = name;}/*** 输出叶子对象的结构*/public void printStruct(String preStr){System.out.println(preStr + "_" + name);}
}

组合对象

package day14组合模式;import java.util.ArrayList;
import java.util.Collection;/*** 组合对象,组合对象里面包含其他的组合对象或者是叶子对象* 由于类型不同,需要分开记录*/
public class Composite {/*** 用来记录包含的其他组合对象*/private Collection<Composite> childComposite = new ArrayList<>();/*** 用来记录包含的其他叶子对象*/private Collection<Leaf> childLeaf = new ArrayList<>();/*** 组合对象的名字*/private String name = "";/*** 构造方法*/public Composite(String name){this.name = name;}/*** 向组合对象加入被它包含的其他组合对象* @param c 被它包含的其他组合对象*/public void addComposite(Composite c){this.childComposite.add(c);}/*** 向组合对象加入被它包含的叶子对象* @param leaf 被它包含的叶子对象*/public void addLeaf(Leaf leaf){this.childLeaf.add(leaf);}/*** 输出组合对象自身的结构*/public void printStruct(String prestr){// 先把自己输出去System.out.println(prestr + "+" + this.name);// 然后添加一个空格,表示向后缩进一个空格,输出自己包含的叶子对象prestr += " ";for (Leaf leaf : childLeaf) {leaf.printStruct(prestr);}// 输出当前对象的子对象了for (Composite c : childComposite) {// 递归输出每个子对象c.printStruct(prestr);}}
}

Client

package day14组合模式;public class Client {public static void main(String[] args) {// 定义所有的组合对象Composite root = new Composite("服装");Composite c1 = new Composite("男装");Composite c2 = new Composite("女装");// 定义所有的叶子对象Leaf leaf1 = new Leaf("衬衣");Leaf leaf2 = new Leaf("夹克");Leaf leaf3 = new Leaf("裙子");Leaf leaf4 = new Leaf("套装");// 按照树的结构来组合 组合对象和叶子对象root.addComposite(c1);root.addComposite(c2);c1.addLeaf(leaf1);c1.addLeaf(leaf2);c2.addLeaf(leaf3);c2.addLeaf(leaf4);// 调用跟对象的输出功能来输出整棵树root.printStruct("");}
}

有何问题 

必须区分组合对象和叶子对象,并进行有区别的对待

解决方案

组合模式

定义:

思路:将组合对象和叶子对象统一起来。通过引入一个抽象的组件对象,作为组合对象和叶子对象的父对象,这样就统一起来了。

代码改造 

抽象父组件对象

package day14组合模式.Component;/*** 抽象的父组件对象*/
public abstract class Component {/*** 输出组件自身的名称*/public abstract void printStruct(String preStr);/*** 向组合对象中加入组件对象* @param child*/public void addChild(Component child){throw new UnsupportedOperationException("对象不支持这个功能");}/*** 从组合对象中移出某个组件对象* @param child*/public void removeChild(Component child){throw new UnsupportedOperationException("对象不支持这个功能");}/*** 返回某个索引对应的组件对象* @param index 需要获取的组件对象的索引,索引从0开始* @return 索引对应的组件对象*/public Component getChildren(int index){throw new UnsupportedOperationException("对象不支持这个功能");}
}

Leaf类

继承一下这个抽象类,别的没有变化

package day14组合模式;import day14组合模式.Component.Component;/*** 叶子对象*/
public class Leaf extends Component {/*** 叶子对象的名字*/private String name = "";/*** 构造方法,传入叶子对象的名字*/public Leaf(String name){this.name = name;}/*** 输出叶子对象的结构*/public void printStruct(String preStr){System.out.println(preStr + name);}
}

组合对象类

package day14组合模式;import day14组合模式.Component.Component;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;/*** 组合对象,组合对象里面包含其他的组合对象或者是叶子对象* 由于类型不同,需要分开记录*/
public class Composite extends Component {/*** 用来存储组合对象中包含的子组件对象*/private List<Component> childComponents = null;/*** 组合对象的名字*/private String name = "";/*** 构造方法*/public Composite(String name) {this.name = name;}public void addChild(Component child) {// 延迟初始化if (childComponents == null) {childComponents = new ArrayList<>();}childComponents.add(child);}/*** 输出组合对象自身的结构*/public void printStruct(String prestr) {// 先把自己输出去System.out.println(prestr + this.name);// 如果还包含有子组件,那么就输出这些子组件对象if (this.childComponents != null) {prestr += " ";// 输出当前对象的子对象了for (Component c : childComponents) {// 递归输出每个子对象c.printStruct(prestr);}}}
}

去掉了之前区分组合对象和叶子对象的方法。

Client

        // 定义所有的组合对象Component root = new Composite("服装");Component c1 = new Composite("男装");Component c2 = new Composite("女装");// 定义所有的叶子对象Component leaf1 = new Leaf("衬衣");Component leaf2 = new Leaf("夹克");Component leaf3 = new Leaf("裙子");Component leaf4 = new Leaf("套装");// 按照树的结构来组合 组合对象和叶子对象root.addChild(c1);root.addChild(c2);c1.addChild(leaf1);c1.addChild(leaf2);c2.addChild(leaf3);c2.addChild(leaf4);// 调用跟对象的输出功能来输出整棵树root.printStruct("");

组合模式优缺点

 

思考 

本质:统一叶子对象和组合对象,一视同仁全部当成Component对象

何时选用

 

相关文章:

研磨设计模式day13组合模式

目录 场景 不用模式实现 代码实现 有何问题 解决方案 代码改造 组合模式优缺点 思考 何时选用 场景 不用模式实现 代码实现 叶子对象 package day14组合模式;/*** 叶子对象*/ public class Leaf {/*** 叶子对象的名字*/private String name "";/**…...

Linux命令(73)之zip

linux命令之zip 1.zip介绍 linux命令zip是用来压缩文件及解压缩文件名称后缀为".zip"的文件 2.zip用法 zip [参数] filename[.zip] zip常用参数 参数说明-r压缩递归处理-d从压缩文件内删除指定的文件-T检查备份文件是否正确无误-u更换较新的文件到压缩文件内-q不…...

深入理解Reactor模型的原理与应用

1、什么是Reactor模型 Reactor意思是“反应堆”&#xff0c;是一种事件驱动机制。 和普通函数调用的不同之处在于&#xff1a;应用程序不是主动的调用某个 API 完成处理&#xff0c;而是恰恰相反&#xff0c;Reactor逆置了事件处理流程&#xff0c;应用程序需要提供相应的接口并…...

微信小程序开发的投票评选系统设计与实现

摘要 越来越多信息化融入到我们生活当中的同时&#xff0c;也在改变着我们的生活和学习方式&#xff0c;当然&#xff0c;变化最明显的除了我们普通民众之外&#xff0c;要数高校学生的生活方式以及校园信息化的变革。智慧是改变生活和生产的一种来源&#xff0c;那么智慧的体…...

【校招VIP】算法考点之堆排

考点介绍&#xff1a; 排序算法属于数据结构和算法的基础内容&#xff0c;并且也是大厂笔试中的高频考点。 堆排序是使用一棵树存储序列这个课树只保证跟节点是这棵树中的最小值&#xff0c;但并不保证其他节点是按顺序的。因此他的排序是每次从堆中取得堆顶&#xff0c;取得 n…...

关于yarn安装时报“node“ is incompatible with this module的解决办法

前提&#xff1a; 在用vue写一个h5页面时&#xff0c;当在用yarn安装时&#xff0c;提示如下错误&#xff1a; The engine “node” is incompatible with this module. Expected version "^14.18.0 || ^16.14.0 || >18. 解决办法 我是使用命令忽略错误&#xff1a…...

开源利器推荐:美团动态线程池框架的接入分享及效果展示

前言 蛮早前有些过关于线程池的使用及参数的一些参考配置&#xff0c;有兴趣的可以翻看以前的博文&#xff0c;但终究无法解决线程池的动态监控和实时修改。 以前读过美团早期发布的动态线程池框架的思路相关文章&#xff0c;但想要独自实现不是一件容易的事。 去年&#xff0c…...

Linux目录结构与文件管理 (02)(四)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、查看文件内容 二、创建文件 三、删除文件 四、 移动文件 五、复制文件 六、编辑文件内容 总结 前言 今天是在昨天的基础上继续学习&#xff0c;主要…...

对1GHz脉冲多普勒雷达进行快速和慢速处理生成5个移动目标的距离多普勒图研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

uni.uploadFile上传 PHP接收不到

开始这样&#xff0c;后端$file $request->file(file);接收不到 数据跑到param中去了 去掉Content-Type&#xff0c;就能接收到了 param只剩下...

2023年高教社杯 国赛数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米&#xff0c;宽为12米&…...

Netty简易聊天室

文章目录 本文目的参考说明环境说明maven依赖日志配置单元测试 功能介绍开发步骤 本文目的 通过一个简易的聊天室案例&#xff0c;讲述Netty的基本使用。同时分享案例代码。项目中用到了log4j2&#xff0c;junit5&#xff0c;同时分享这些基础组件的使用。项目中用到了awt&…...

Flutter Cannot run with sound null safety, because the following dependencies

flutter sdk 版本升级到2.0或者更高的版本后&#xff0c;运行之前的代码会报错 Error: Cannot run with sound null safety, because the following dependencies dont support null safety:- package:flutter_swiper- package:flutter_page_indicator- package:transformer_p…...

利用改进的遗传算法(种群隔离与个体迁移)mpi并行解决tsp问题

序 关于tsp问题的概述以及如何使用遗传算法进行求解已经在上一篇文章中说明了&#xff1a;遗传算法解决TSP问题. 但是&#xff0c;作为一种演化算法&#xff0c;遗传算法还存在着许多问题&#xff0c;比如早熟的情况&#xff0c;很容易在算法前期就已经收敛了&#xff0c;大量…...

【C++】—— C++11之线程库

前言&#xff1a; 在本期&#xff0c;我将给大家介绍的是 C11 中新引进的知识&#xff0c;即关于线程库的相关知识。 目录 &#xff08;一&#xff09;线程库的介绍 1、线程库的由来 2、线程库的简单介绍 &#xff08;二&#xff09;线程函数参数 &#xff08;三&#xf…...

前端面试:【性能优化】前端缓存、CDN、懒加载和预加载

亲爱的前端开发者&#xff0c;Web性能对用户体验至关重要。如果你想让你的网站更快、更具吸引力&#xff0c;就需要关注前端性能优化。在这篇文章中&#xff0c;我们将深入探讨四个关键的性能优化策略&#xff1a;前端缓存、CDN&#xff08;内容分发网络&#xff09;、懒加载和…...

民族传统文化分享系统uniapp 微信小程序

管理员、用户可通过Android系统手机打开系统&#xff0c;注册登录后可进行管理员后端&#xff1b;首页、个人中心、用户管理、知识分类管理、知识资源管理、用户分享管理、意见反馈、系统管理&#xff0c;用户前端&#xff1b;首页、知识资源、用户分享、我的等。 本系统的使用…...

netty(二):NIO——处理可写事件

处理可写事件 什么情况下需要注册可写事件&#xff1f; 在服务端一次性无法把数据发送完的情况下&#xff0c;需要注册可写事件 服务端一次性是否能够把数据全部发送完成取决于服务端的缓冲区大小&#xff0c;该缓冲区不受程序控制 注册可写事件的步骤 判断ByteBuffer是否仍…...

PHP基本语法解析与应用指南

PHP&#xff08;Hypertext Preprocessor&#xff09;是一种广泛应用的开源脚本语言&#xff0c;特别适用于Web开发。本文将深入探讨PHP的基本语法&#xff0c;包括变量、数据类型、运算符、控制流等方面的内容。我们将详细介绍每个主题的基本概念、语法规则和常见应用&#xff…...

ICS PA1

ICS PA1 init.shmake 编译加速ISA计算机是个状态机程序是个状态机准备第一个客户程序parse_argsinit_randinit_loginit_meminit_isa load_img剩余的初始化工作运行第一个客户程序调试&#xff1a;零断点TUI 基础设施单步执行打印寄存器状态扫描内存 表达式求值词法分析递归求值…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...