设计模式:生活中的组合模式
想象一下,你正在组织一个大型的家庭聚会。在这个聚会中,你需要准备各种菜肴,每个菜肴又包含不同的食材。你的目标是能够以统一的方式处理整个聚会的准备工作,不论是处理单个食材还是一整道菜肴。
在这个场景中,我们可以将“菜肴”看作是组合对象,“食材”看作是叶子节点。整个家庭聚会的准备工作就是一个“部分-整体”的层次结构,与组合模式中的结构类似。
家庭聚会的组合模式类比
- 整体(Composite):整个聚会的菜单,包含了多个菜肴,每个菜肴又可以包含其他菜肴或者单独的食材。
- 部分(Leaf):单个食材,如西红柿、黄瓜等,不再包含其他食材。
- 共同接口(Component):菜肴和食材都可以通过某些共同的操作来处理,例如“准备”或“展示”。
实际例子
假设你需要准备以下菜肴:
- 沙拉(Composite):包含西红柿(Leaf)、黄瓜(Leaf)和生菜(Leaf)。
- 烤肉(Composite):包含牛肉(Leaf)和调料(Composite),调料又包含盐(Leaf)和黑胡椒(Leaf)。
这里,沙拉和烤肉都是可以由更小部分组成的复合菜肴,而西红柿、黄瓜、生菜、牛肉、盐和黑胡椒都是基本的食材,没有进一步的分解。
在准备这个聚会时,你不必关心每个菜肴的具体组成。你可能会有一个统一的流程来“准备”每个菜肴,无论它是一个复合菜肴还是一个单一食材。这就是组合模式的精髓:客户端代码可以忽略对象之间的复杂层次差异,统一对待所有对象。
代码实现类比
如果我们要将这个场景转换成代码,可能如下:
// 共同接口
interface PartyItem {void prepare();
}// 叶子节点
class Ingredient implements PartyItem {private String name;public Ingredient(String name) {this.name = name;}@Overridepublic void prepare() {System.out.println("Preparing " + name);}
}// 组合对象
class Dish implements PartyItem {private String name;private List<PartyItem> ingredients = new ArrayList<>();public Dish(String name) {this.name = name;}public void add(PartyItem item) {ingredients.add(item);}@Overridepublic void prepare() {System.out.println("Preparing dish: " + name);for (PartyItem item : ingredients) {item.prepare();}}
}
在上述代码中,Dish
可以包含其他 Dish
对象或 Ingredient
对象,而 Ingredient
是基本的食材。prepare
方法为统一的操作,既可以准备单个食材,也可以准备整个菜肴。
总结
通过这个日常生活中的类比,我们可以看到组合模式如何在软件设计中发挥作用。它允许我们以统一的方式操作单个对象和组合对象,简化了客户端代码,并使得整个结构更加灵活。在设计系统时,考虑到部分-整体的关系,可以帮助我们更好地应用组合模式。
相关文章:
设计模式:生活中的组合模式
想象一下,你正在组织一个大型的家庭聚会。在这个聚会中,你需要准备各种菜肴,每个菜肴又包含不同的食材。你的目标是能够以统一的方式处理整个聚会的准备工作,不论是处理单个食材还是一整道菜肴。 在这个场景中,我们可…...
WPF OnStartup
在Windows Presentation Foundation (WPF)框架中,OnStartup 是 System.Windows.Application 类的一个受保护的虚方法,它是应用程序启动过程中的一个重要环节。当一个 WPF 应用程序启动时,其入口点通常是 App.xaml 文件和对应的后台代码文件 A…...
docker-相关
打镜像 1、编写dockfile文件,请自行百度 2、docker build -t 镜像名称:版本号 dockerFile路径 3、docker save -o 镜像压缩包名称.tar 镜像名称:镜像版本号 部署镜像 1、将镜像tar包放到部署机器上 2、加载镜像:docker load -i 镜像tar包路径 3、dock…...
二十、Rust AOP 切面增强
用过 java spring 的同学,应该会对 AspectJ 的 前置、后置、环绕 增强 念念不忘,巧了 rust 也有类似能力,稍显不同的是,为了向 “零成本抽象” 靠齐,Rust 的 “增强” 是在编译期 完成的。 编译期生成,则离…...
掌握Go语言:Go语言精细错误,清晰、高效的错误处理实践(32)
错误处理是任何编程语言中都至关重要的一部分,Go 语言提供了一套简单而强大的错误处理机制,使得处理错误变得高效而清晰。 Go 错误类型 在 Go 中,错误是一个普通的接口类型,即 error 接口,其定义如下: t…...
Spring与Web环境的集成
1. ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置文件加载多…...

二叉树的遍历——bfs广度优先搜索
1、BinNode类的创建 (1)代码总览 ##(2)测试示例 2、二叉树的遍历 (1)图示 (2)代码总览 (3)测试示例...

飞鸟写作可靠吗 #职场发展#经验分享#经验分享
飞鸟写作是一个非常便捷的论文写作工具,不仅可以帮助用户高效地完成论文写作,还可以提供查重降重的功能,帮助用户确保论文的原创性。那么,飞鸟写作到底可靠吗?答案是肯定的。 首先,飞鸟写作提供的查重降重功…...

Java 实现自定义注解
一、interface 关键字 我们想定义一个自己的注解 需要使用 interface 关键字来定义。 如定义一个叫 MyAnnotation 的注解: public interface MyAnnotation { } 二、元注解 光加上 interface 关键字 还不够,我们还需要了解5大元注解 RetentionTargetDo…...
代码随想录Day48
Day 48 动态规划part09 今日任务 198.打家劫舍213.打家劫舍II337.打家劫舍III 代码实现 基础打家劫舍 class Solution {public static int rob(int[] nums) {if (nums null || nums.length 0) return 0;if (nums.length 1) return nums[0];int[] dp new int[nums.leng…...

Web 后台项目,权限如何定义、设置、使用:菜单权限、按钮权限 ts element-ui-Plus
Web 后台项目,权限如何定义、设置、使用:菜单权限、按钮权限 ts element-ui-Plus 做一个后台管理项目,里面需要用到权限管理。这里说一下权限定义的大概,代码不多,主要讲原理和如何实现它。 一、权限管理的原理 权限…...
ADB 操作命令及其详细用法
adb devices 用途:列出连接到计算机的所有 Android 设备。详解:执行该命令后,ADB 将扫描连接到计算机的所有 Android 设备,并列出它们的序列号。 adb connect <device> 用途:连接到指定 IP 地址的 Android 设备。…...

类的函数成员(三):拷贝构造函数
一.什么是拷贝构造函数? 1.1 概念 同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或称拷贝是完全可行的。这个拷贝过程只需要拷贝数据成员,而函数成员是共用的(只有一份拷贝)。 在建立对象…...

C#操作MySQL从入门到精通(8)——对查询数据进行高级过滤
前言 我们在查询数据库中数据的时候,有时候需要剔除一些我们不想要的数据,这时候就需要对数据进行过滤,比如学生信息中,我只需要年龄等于18的,同时又要家乡地址是安徽的,类似这种操作专栏第7篇的C#操作MySQL从入门到精通(7)——对查询数据进行简单过滤简单过滤方法就无法…...

Centos 7 安装通过yum安装google浏览器
在CentOS 7上使用yum安装Google Chrome浏览器稍微复杂一些,因为Chrome并不直接包含在默认的Yum仓库中。按照以下步骤来操作: 1、添加Google Chrome仓库 首先,您需要手动添加Google Chrome的Yum仓库。打开终端,并使用文本编辑器&a…...
题目:学习使用按位与 。
题目:学习使用按位与 & 。 There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about being cheated shoul…...

逐步分解,一文教会你如何用 jenkins+docker 实现主从模式
jenkins 主从模式想必大家都不陌生,大家在学习过程中为了学习方便都在自己本地搭建了 jenkins 环境,然后通过 javaweb 方式实现,对于 docker 下实现主从模式大家好像兴趣挺大。 今天就通过这篇文章给大家讲讲怎么玩,希望对大家有…...
WebSocket 对于手游的意义
WebSocket作为一个HTTP的升级协议,其实对HTTP协议用的不多,主要是消息头相关部分,WebScoket协议最初的动机应该是给网页应用增加一个更贴近实时环境的通讯方式,让某些网页应用得到更佳的通讯质量(双工,低延…...
安卓APP的技术质量:如何提高
安卓APP的技术质量:如何提高 技术质量包括稳定性和性能,还有资源工具化程序.你的APP 的技术质量能够影响你的用户体验.一个高质量的体验不仅 最小化了技术问题的存在,而且也最大化地利用了安卓操作 系统和设备硬件的能力. 为了构建一个高质量的APP,遵循如下的指导原则: 形式因…...

二分查找 -- 力扣(LeetCode)第704题
题目 https://leetcode.cn/problems/binary-search/description/ 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 示例…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...