研磨设计模式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意思是“反应堆”,是一种事件驱动机制。 和普通函数调用的不同之处在于:应用程序不是主动的调用某个 API 完成处理,而是恰恰相反,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并…...
微信小程序开发的投票评选系统设计与实现
摘要 越来越多信息化融入到我们生活当中的同时,也在改变着我们的生活和学习方式,当然,变化最明显的除了我们普通民众之外,要数高校学生的生活方式以及校园信息化的变革。智慧是改变生活和生产的一种来源,那么智慧的体…...
【校招VIP】算法考点之堆排
考点介绍: 排序算法属于数据结构和算法的基础内容,并且也是大厂笔试中的高频考点。 堆排序是使用一棵树存储序列这个课树只保证跟节点是这棵树中的最小值,但并不保证其他节点是按顺序的。因此他的排序是每次从堆中取得堆顶,取得 n…...
关于yarn安装时报“node“ is incompatible with this module的解决办法
前提: 在用vue写一个h5页面时,当在用yarn安装时,提示如下错误: The engine “node” is incompatible with this module. Expected version "^14.18.0 || ^16.14.0 || >18. 解决办法 我是使用命令忽略错误:…...
开源利器推荐:美团动态线程池框架的接入分享及效果展示
前言 蛮早前有些过关于线程池的使用及参数的一些参考配置,有兴趣的可以翻看以前的博文,但终究无法解决线程池的动态监控和实时修改。 以前读过美团早期发布的动态线程池框架的思路相关文章,但想要独自实现不是一件容易的事。 去年,…...
Linux目录结构与文件管理 (02)(四)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、查看文件内容 二、创建文件 三、删除文件 四、 移动文件 五、复制文件 六、编辑文件内容 总结 前言 今天是在昨天的基础上继续学习,主要…...
对1GHz脉冲多普勒雷达进行快速和慢速处理生成5个移动目标的距离多普勒图研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
uni.uploadFile上传 PHP接收不到
开始这样,后端$file $request->file(file);接收不到 数据跑到param中去了 去掉Content-Type,就能接收到了 param只剩下...
2023年高教社杯 国赛数学建模思路 - 复盘:光照强度计算的优化模型
文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米,宽为12米&…...
Netty简易聊天室
文章目录 本文目的参考说明环境说明maven依赖日志配置单元测试 功能介绍开发步骤 本文目的 通过一个简易的聊天室案例,讲述Netty的基本使用。同时分享案例代码。项目中用到了log4j2,junit5,同时分享这些基础组件的使用。项目中用到了awt&…...
Flutter Cannot run with sound null safety, because the following dependencies
flutter sdk 版本升级到2.0或者更高的版本后,运行之前的代码会报错 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问题的概述以及如何使用遗传算法进行求解已经在上一篇文章中说明了:遗传算法解决TSP问题. 但是,作为一种演化算法,遗传算法还存在着许多问题,比如早熟的情况,很容易在算法前期就已经收敛了,大量…...
【C++】—— C++11之线程库
前言: 在本期,我将给大家介绍的是 C11 中新引进的知识,即关于线程库的相关知识。 目录 (一)线程库的介绍 1、线程库的由来 2、线程库的简单介绍 (二)线程函数参数 (三…...
前端面试:【性能优化】前端缓存、CDN、懒加载和预加载
亲爱的前端开发者,Web性能对用户体验至关重要。如果你想让你的网站更快、更具吸引力,就需要关注前端性能优化。在这篇文章中,我们将深入探讨四个关键的性能优化策略:前端缓存、CDN(内容分发网络)、懒加载和…...
民族传统文化分享系统uniapp 微信小程序
管理员、用户可通过Android系统手机打开系统,注册登录后可进行管理员后端;首页、个人中心、用户管理、知识分类管理、知识资源管理、用户分享管理、意见反馈、系统管理,用户前端;首页、知识资源、用户分享、我的等。 本系统的使用…...
netty(二):NIO——处理可写事件
处理可写事件 什么情况下需要注册可写事件? 在服务端一次性无法把数据发送完的情况下,需要注册可写事件 服务端一次性是否能够把数据全部发送完成取决于服务端的缓冲区大小,该缓冲区不受程序控制 注册可写事件的步骤 判断ByteBuffer是否仍…...
PHP基本语法解析与应用指南
PHP(Hypertext Preprocessor)是一种广泛应用的开源脚本语言,特别适用于Web开发。本文将深入探讨PHP的基本语法,包括变量、数据类型、运算符、控制流等方面的内容。我们将详细介绍每个主题的基本概念、语法规则和常见应用ÿ…...
ICS PA1
ICS PA1 init.shmake 编译加速ISA计算机是个状态机程序是个状态机准备第一个客户程序parse_argsinit_randinit_loginit_meminit_isa load_img剩余的初始化工作运行第一个客户程序调试:零断点TUI 基础设施单步执行打印寄存器状态扫描内存 表达式求值词法分析递归求值…...
Java学数据结构(4)——散列表Hash table 散列函数 哈希冲突
目录 引出散列表Hash table关键字Key和散列函数(hash function)散列函数解决collision哈希冲突(碰撞)分离链接法(separate chaining)探测散列表(probing hash table)双散列(double hashing) Java标准库中的散列表总结 引出 1.散列表,key&…...
OVRL-V2: A simple state-of-art baseline for IMAGENAV and OBJECTNAV 论文阅读
论文信息 题目:OVRL-V2: A simple state-of-art baseline for IMAGENAV and OBJECTNAV 作者:Karmesh Yadav, Arjun Majumdar, Ram Ramrakhya 来源:arxiv 时间:2023 代码地址: https://github.com/ykarmesh…...
【安全】原型链污染 - Hackit2018
目录 准备工作 解题 代码审计 Payload 准备工作 将这道题所需依赖模块都安装好后 运行一下,然后可以试着访问一下,报错是因为里面没内容而已,不影响,准备工作就做好了 解题 代码审计 const express require(express) var hbs require…...
net.ipv4.ip_forward=0导致docker容器无法与外部通信
在启动一个docker容器时报错: WARNING: IPv4 forwarding is disabled. Networking will not work. 并且,此时本机上的其他容器的网络服务,只能在本机上访问,其他机器上访问不到。 原因: sysctl net.ipv4.ip_forward …...
软考高级系统架构设计师系列论文九十八:论软件开发平台的选择与应用
软考高级系统架构设计师系列论文九十八:论软件开发平台的选择与应用 一、相关知识点二、摘要三、正文四、总结一、相关知识点 软考高级系统架构设计师系列之:面向构件的软件设计,构件平台与典型架构二、摘要 本文讨论选择新软件开发平台用于重新开发银行中间业务系统。银行中…...
Springboot整合WebFlux
一、使用WebFlux入门 WebFlux整合MysqlWebFlux整合ESWebFlus整合MongdbWebFlus整合Redis 1、添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId><version>2.2.1.…...
uniapp 实现地图距离计算
在uniapp中实现地图距离计算可以借助第三方地图服务API来实现。以下是一种基本的实现方式: 注册地图服务API账号:你可以选择使用高德地图、百度地图等提供地图服务的厂商,注册一个开发者账号并获取API密钥。 安装相关插件或SDK:根…...
破除“中台化”误区,两大新原则考核中后台
近年来,“中台化”已成为许多企业追求的目标,旨在通过打通前后台数据和业务流程,提升运营效率和创新能力。然而,在实施过程中,一些误解可能导致“中台化”未能如预期般发挥作用。本文将探讨这些误解,并提出…...
基于YOLOV8模型和Kitti数据集的人工智能驾驶目标检测系统(PyTorch+Pyside6+YOLOv8模型)
摘要:基于YOLOV8模型和Kitti数据集的人工智能驾驶目标检测系统可用于日常生活中检测与定位车辆、汽车等目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用…...
基于Android的课程教学互动系统 微信小程序uniapp
教学互动是学校针对学生必不可少的一个部分。在学校发展的整个过程中,教学互动担负着最重要的角色。为满足如今日益复杂的管理需求,各类教学互动程序也在不断改进。本课题所设计的springboot基于Android的教学互动系统,使用SpringBoot框架&am…...
html做的小网站/天津网站seo设计
经常有人提问:说自己的项目是由许多DLL打包方式组织的,各个DLL之间的对象如何共享访问? 这其实很简单:只要共享对象创建后,把它的指针保存进一个大家都可以访问 的地方,需要的时候就去取。 我说用INI文件暂…...
wordpress手机端源码/乌海网站seo
最近在工作中要实现一种“流程审批”的功能,查阅资料得知,workFlow技术可以满足我的需求,于是就开始沉下心来好好学习一下这门技术。总结的学习资料也拿出来和大家共享一下。 什么是工作流: 工作流,指的是一系列相互衔接、自动进行…...
wordpress主题域名限制破解/seo单页面优化
首先我们先看流程图,了解一下大致结构。 其中,index.html文件为空白页,代码如下: <html> <head> <title> index </title> </head> </html> new1~3.html文件的作用是将页面背景颜色改变&…...
威海做网站多少钱/制作网站代码
什么是Mybatis?众所周知,MyBatis 是一款非常优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。不仅避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。还可以使用简单的 XML 或注解来配置和映射原生信息,将接口…...
dw做六个页面的网站/今日头条新闻大事
转自:http://blog.csdn.net/totogo2010/article/details/9100767 准备2个文件: 文件一,ThisService.app文件二,Doxygen.rb下载上述2个文件:ThisService&Doxygen_rb准备好之后,两步配置,一步…...
做网站是个什么行业/福州百度首页优化
正确答案是 CD接口很重要,为了说明情况,这里稍微啰嗦点:(1)接口用于描述系统对外提供的所有服务,因此接口中的成员常量和方法都必须是公开(public)类型的,确保外部使用者能访问它们;(2)接口仅仅描述系统能做什么,但不指明如何去做…...