《论文阅读21》Equivariant Multi-View Networks
一、论文
- 研究领域:计算机视觉 | 多视角数据处理中实现等变性
- 论文:Equivariant Multi-View Networks
-
ICCV 2019
- 论文链接
- 视频链接
二、论文简述
在计算机视觉中,模型在不同视角下对数据(例如,点云、图像等)对数据的变化具有一定的响应性。为了使模型能够更好地适应这种变化,不是仅仅对某个特定视角的数据进行训练,研究人员提出了等变多视角网络的概念。能够同时处理多视角数据,并通过共享权重或其他机制来保持数据的等变性。
三、论文详述
等变多视图网络
- Abstract
利用在自然图像上预先训练好的深度神经网络独立处理输入图像的多个视图,通过对所有视图进行一轮pooling来实现视图排列不变性。我们认为,这种操作会丢弃重要信息,并导致不合格的全局描述符。在本文中,我们提出了一种多视图聚合的群卷积方法,即在旋转群的离散子群上进行卷积,从而能够以等变(而非不变)的方式对所有视图进行联合推理,直至最后一层。我们进一步发展了这一想法,以便在旋转组中更小的离散同质空间上进行操作,在这里使用极视图表示法,只需输入视图数量的一小部分就能保持等变关系。我们在多个大型三维形状检索任务中确立了新的技术水平,并展示了在全景场景分类中的其他应用。
- 先前工作:利用在自然图像上预先训练好的深度神经网络独立处理输入图像的多个视图,通过对所有视图进行一轮pooling来实现视图排列不变性
- 我们工作:我们提出了一种多视图聚合的群卷积方法,即在旋转群的离散子群上进行卷积,从而能够以等变(而非不变)的方式对所有视图进行联合推理,直至最后一层。
视图排列不变性(Viewpoint Permutation Invariance)是指在处理三维数据(如点云、3D模型)时,模型对不同视角或观察角度的变化具有不变性。在点云处理中,由于点云的点的顺序和排列可能会在不同视角下发生变化,保持对这些排列变化的不变性对于实现稳健的特征提取和分析至关重要。
视图排列不变性对于点云处理中的许多任务非常重要,如点云分类、分割、目标检测等。实现视图排列不变性可以避免模型仅仅学习特定视角下的特征,使得模型能够更好地泛化到不同视角的点云数据。
以下是一些方法和思路,可以帮助实现视图排列不变性:
1. 捕捉点云在不同视角下的特征,并保持在球面上的等变性。
2. 设计旋转不变的特征提取方法,确保不同视角下的点云特征保持一致。
3. 在训练时,通过应用随机的旋转变换来增加数据的多样性,帮助模型学习不同视角下的特征。
4. 将从不同视角提取的特征进行融合,以生成更综合的特征表示。
5. **点云对齐**:在训练前对点云进行对齐,使得不同视角下的点对应关系更一致。
多视图聚合:整合多个视角(或多个输入)的信息
Joint Reasoning Over All Views: 这个方法允许在所有视角上进行联合推理,这意味着模型能够考虑来自不同视角的信息,并在处理数据时保持这种多视角的信息。
旋转群(Rotation Group)的一个离散子群是指旋转群中的一个子集,其中包含一组离散的旋转操作。常见的例子是在三维空间中,使用Z轴的离散旋转操作来构成一个离散子群。这意味着我们只考虑绕Z轴旋转一定角度的操作,而不考虑其他轴的旋转。这个子群是离散的,因为我们只考虑一些特定的旋转角度,而不是考虑所有可能的连续旋转。
旋转群是一个连续的、无限的群,包含了所有可能的连续旋转操作。然而,当我们考虑到计算或离散的问题时,有时会使用旋转群的一个子集来简化问题或进行计算。
SO(3) 旋转群由所有保持三维空间中原点不动的旋转操作组成。这些操作可以用三维旋转矩阵表示,其中包括绕任意轴的旋转。旋转群的元素可以表示为一个 3x3 的正交矩阵,具有特殊行列式等于1的性质。
- Introduction
随着大规模物体三维数据集[39, 3]和整个场景数据集[2, 8]的激增,可以对深度学习模型进行训练,生成可用于分类和检索任务的全局描述符。
对深度学习模型进行训练,生成可用于分类和检索任务的全局描述符
出现的第一个挑战是如何表示输入。尽管在体积[39, 24]、点云[27, 32]和基于网格[23, 26]的表示方面进行了大量尝试,但使用三维输入的多个视图可以切换到二维域,在二维域中可以直接应用最近所有基于图像的深度学习突破(例如[15]),从而促进最先进的性能[33, 20]。
基于多视图(MV)的方法需要某种形式的视图池化,它可以是
(1)在一些中间卷积层上的逐像素池化[33],
(2)在最终的1D视图描述符上池化[34],
(3)组合最终的logits [20],这可以被视为独立投票。这些操作对于查看排列通常是不变的。
我们的主要观点是,传统的视图池化是在对视图集进行任何联合处理之前进行的,不可避免地会丢弃有用的特征,从而导致描述符不合格。为了解决这个问题,我们首先认识到,每个视图都可以与旋转群 SO(3) 的一个元素相关联,因此将多个视图组合起来的自然方法就是将其作为旋转群上的一个函数。
- 传统的视图池化是在对视图集进行任何联合处理之前进行的,不可避免地会丢弃有用的特征,从而导致描述符不合格
- 每个视图都可以与旋转群 SO(3) 的一个元素相关联,因此将多个视图组合起来的自然方法就是将其作为旋转群上的一个函数。
我们采用传统的 CNN 来获取组成该函数的视图描述符。我们设计了一个组卷积网络(G-CNN,灵感来自文献[5])来学习对组的变换具有等变性的表征。我们通过对最后一个 G-CNN 层进行池化,获得了对分类和检索有用的不变描述符。我们的 G-CNN 在组上具有局部支持的描述符,并且随着层数的增加和感受域的扩大,可以学习到更复杂的分层描述符。
我们利用了多视图的有限性,并考虑了二十面体等有限旋转群,这与 [6, 10] 在连续群上的操作不同。为了减少处理每个群元素一个视图的计算成本,我们证明,通过考虑与平面内扩张旋转群(对数极坐标)有关的典型坐标视图,我们可以大大减少视图的数量,并获得同质空间(H 空间)上的初始表示,该表示可以通过相关性提升,同时保持等差关系。
我们专注于3D形状,但我们的模型适用于任何任务,多个视图可以表示输入,如全景场景的实验所示。
等变特征(Equivariant Features)指的是在输入数据的某种变换下,特征在一定的方式下也进行相应的变换。在计算机视觉和深度学习中,等变性是一种重要的性质,特别是在处理具有变换对称性的数据时,如图像、点云和三维模型等。
等变特征对于保持输入数据的变换性质非常有用,因为它们能够更好地捕捉数据的关键特征,从而提高模型的泛化能力和性能。例如,对于三维点云数据,等变特征可以在数据进行旋转、平移等操作时,保持相应的特征变化,从而使模型更好地适应不同的视角和变换。
在点云处理中,等变特征的实现涉及到了一些专门的方法和技术,例如:
1. **旋转等变性**:通过设计神经网络架构,使得网络在输入数据旋转时,特征也相应地进行旋转,从而实现旋转等变性。
2. **球面卷积神经网络(Spherical CNNs)**:用于处理球面数据(如球面点云)的网络,能够在球面上保持旋转等变性,从而在点云的不同视角下提取有意义的特征。
3. **基于变换矩阵的操作**:使用变换矩阵来定义点云的变换,然后在神经网络中将这些变换操作纳入,以捕捉等变特征。
4. **群卷积神经网络(Group CNNs)**:设计网络结构,使其在特定的群(如旋转群)变换下具有等变性,从而能够处理变换对称性数据。
实现等变特征通常需要深入的数学和几何知识,以确保模型在数据变换时能够正确地捕捉和表示特征。这在处理点云等不规则数据时尤其重要,因为这些数据没有像图像那样的固定结构,需要特殊的处理方法来实现等变性。
组卷积(Group Convolution)是一种卷积神经网络(CNN)中的操作,用于处理具有一定对称性或结构的数据。组卷积在一定程度上保持输入数据的特定对称性,从而可以更有效地捕获数据的特征。
在组卷积中,卷积核被分成多个组(groups),每个组内的卷积核只与对应组内的输入通道进行卷积操作。这种分组操作有助于实现特定的等变性,使模型能够更好地处理具有变换对称性的数据。
例如,在处理RGB图像时,可以将三个颜色通道(红、绿、蓝)分成不同的组,然后在每个组内分别进行卷积操作。这种操作保持了颜色通道之间的对称性,从而有助于提取有关颜色特征的信息。
在点云处理中,组卷积也可以应用。如果点云数据有一定的结构或对称性,可以将点云分成不同的组,然后在每个组内应用卷积操作,以保持数据的等变性。
组卷积的优点包括:
1. **减少参数和计算量**:由于卷积核被分组,组卷积可以降低参数的数量和计算量,从而在一定程度上加快训练和推理的速度。
2. **保持特定的对称性**:组卷积可以帮助模型捕捉输入数据特定的对称性或结构,从而提高模型的性能。
3. **降低过拟合**:分组操作可以限制每个组内的参数共享,有助于减少过拟合的风险。
需要注意的是,组卷积适用于一些具有特定对称性或结构的数据,但不是适用于所有情况。在设计网络架构时,需要根据数据的特点和任务的要求来决定是否使用组卷积。
图1展示了我们的模型。我们的贡献是:
- 我们引入了一种新颖的方法来聚合多个视图,无论是三维形状的 "由外而内 "视图,还是全景视图的 "由内而外 "视图。我们的模型利用了底层组结构,从而产生了等变特征,这些特征是旋转组的函数。
- 我们介绍了一种既能减少视图数量又能保持等差性的方法,即通过平面内旋转转换为典型坐标,然后进行同质空间卷积。
- 我们探索了有限旋转群和齐次空间,并在迄今为止最大的群--二十面体群上提出了一个离散的G-CNN模型。我们进一步探讨这个组的过滤器本地化的概念。
- 我们在多个形状检索基准上实现了最先进的性能,无论是在规范的姿势和旋转扰动,并显示应用于全景场景分类
图 1:我们的等变多视图网络将多个视图聚合为旋转组上的函数,并通过组卷积进行处理。这保证了三维旋转的等方差性,并允许对所有视图进行联合推理,从而获得卓越的形状描述符。二十面体组上的矢量值函数显示在五面十二面体上,相应的同质空间(H 空间)上的函数显示在十二面体和二十面体上。每个视图首先由一个 CNN 进行处理,由此产生的描述符与一个组(或 H 空间)元素相关联。当视图被识别为一个 H 空间时,第一个操作就是将特征提升到组的相关性。一旦我们有了组的初始表示,就可以应用组 CNN。
- Related work
3D形状分析
3D形状分析的性能在很大程度上取决于输入表示。主要的表示是体积、点云和多视图。
体积方法的早期示例是[3],其引入了ModelNet数据集并使用基于体素表示的深度置信网络训练了3D形状分类器;和[24],其提出了具有3D卷积层和全连接层的标准架构。
Su等人[33]意识到,通过渲染3D输入的多个视图,可以将基于图像的CNN的能力转移到3D任务。他们表明,即使只使用输入的单个视图,传统的CNN也可以优于体积方法,而多视图(MV)模型进一步提高了分类准确性。
Qi等人[28]研究了体积和多视图方法,并提出了对两者的改进; Kanezaki等人[20]引入了一种MV方法,该方法通过联合预测类别和姿态来实现最先进的分类性能,但没有显式的姿态监督。
GVCNN [12]试图学习如何联合收割机不同的视图描述符以获得视图组形状表示;它们将特征的任意组合称为“组”。这与我们使用的术语“群”是代数定义的不同
基于点云的方法[27]实现了体积和多视图之间的中间性能,但在计算上更高效。虽然网格可以说是最自然的表示,并广泛用于计算机图形学,但直接在网格上操作的学习模型只取得了有限的成功[23,26]。
为了更好地比较3D形状描述符,我们将专注于检索性能。最近的方法在检索方面显示了显著的改进:You等人。[41]结合了点云和MV表示; Yavartanoo等人[40]介绍了多视点赤平投影;和Han et al.[14]实现了一种递归MV方法。
我们还考虑了旋转ModelNet和包含旋转形状的SHREC'17 [29]检索挑战上更具挑战性的任务。任意旋转的存在激发了等变表示的使用。
等变表示
为了处理任意方向的三维形状,已经引入了许多变通方法。典型的例子包括训练时间旋转增强和/或测试时间投票[28],以及学习初始旋转到标准姿势[27]。文献[33]中的视图池对输入视图集的排列是不变的。
处理旋转的原则性方法是使用设计为等变的表示。将等方差嵌入CNN的方法主要有三种。
第一种方式是约束滤波器结构,这类似于基于Lie生成器的方法[30,17]。Worral等人[38]利用圆谐波将平移和2D旋转等方差都引入CNN。类似地,托马斯et al.[35]引入张量场以保持3D点云的平移和旋转等变性。
第二种方式是通过坐标的改变;[11,18]对输入进行对数极坐标变换,并将关于单个点的旋转和缩放等方差转换为平移等方差。
第三种方法是利用等变过滤轨道。Cohen 和 Welling 利用正方形旋转组提出了组卷积(G-CNNs)[5],后来又扩展到六边形[19]。Worrall 和 Brostow [37] 在三维体素化数据上使用克莱因四组提出了 CubeNet。Winkels 等人[36]在八面体对称群上对容积 CT 图像实施了三维群卷积。Cohen 等人[7]最近考虑了二十面体上的函数,但他们的卷积是在循环群上,而不是像我们一样在二十面体上。Esteves 等人[10]和 Cohen 等人[6]则侧重于无限群 SO(3),并使用球面谐波变换来精确实现球面卷积或相关。这些方法的主要问题是,输入的球面表示无法捕捉物体形状的复杂性;而且效率较低,面临带宽挑战。
- Preliminaries
我们寻求利用数据中的对称性。对称性是一种保留对象的某些结构的操作。如果对象是一个没有附加结构的离散集合,则每个操作都可以被视为其元素的排列。
术语群用于集合的经典代数定义,其运算满足闭包、结合性、恒等式和反演性质。像置换这样的变换群是“抽象群和对称概念之间缺失的环节”[25]。
我们将视图称为从定向相机拍摄的图像。这不同于参考光轴方向的视点,对于指向固定对象的移动相机而言,从外向内,或者对于指向不同方向的固定相机而言,从内向外。可以从同一视点拍摄多个视图;它们通过平面内旋转相关。
从外向内:对于指向不同方向的固定相机
从内向外:从同一视点拍摄多个视图
Equivariance
通过设计等变的表示是利用对称性的有效方法。 考虑一个集合X和一个变换群G。考虑一个集合X和一个变换群G。
相关文章:

《论文阅读21》Equivariant Multi-View Networks
一、论文 研究领域:计算机视觉 | 多视角数据处理中实现等变性论文:Equivariant Multi-View Networks ICCV 2019 论文链接视频链接 二、论文简述 在计算机视觉中,模型在不同视角下对数据(例如,点云、图像等࿰…...

【数据结构】| 并查集及其优化实现
目录 一. 并查集基本概念处理过程初始化合并查询小结 二. 求并优化2.1 按大小求并2.2 按秩(高度)求并2.3 路径压缩2.4 类的实现代码2.5 复杂度分析 三. 应用LeetCode 128: 最长连续数列LeetCode 547: 省份数量LeetCode 200: 岛屿数量 一. 并查集基本概念 以一个直观的问题来引入…...

最新ChatGPT程序源码+AI系统+详细图文部署教程/支持GPT4.0/支持Midjourney绘画/Prompt知识库
一、AI系统 如何搭建部署人工智能源码、AI创作系统、ChatGPT系统呢?小编这里写一个详细图文教程吧!SparkAi使用Nestjs和Vue3框架技术,持续集成AI能力到AIGC系统! 1.1 程序核心功能 程序已支持ChatGPT3.5/GPT-4提问、AI绘画、Mi…...

自动驾驶和辅助驾驶系统的概念性架构(一)
摘要: 本文主要介绍包括功能模块图,涵盖了底层计算单元、示例工作负载和行业标准。 前言 本文档参考自动驾驶计算联盟(Autonomous Vehicle Computing Consortium)关于自动驾驶和辅助驾驶计算系统的概念系统架构。 该架构旨在与SAE L1-L5级别的自动驾驶保…...

【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之数码管静态显示(四)
本原创教程由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处 适用于板卡型号: 紫光同创PGL22G开发平台(盘古22K) 一:盘古22K开发板(紫光同创PGL22G开发…...

【洛谷】P3853 路标设置
原题链接:https://www.luogu.com.cn/problem/P3853 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 整体思路:二分答案 由题意知,公路上相邻路标的最大距离定义为该公路的“空旷指数”。在公路上增设一些路标&…...

探索图像数据中的隐藏信息:语义实体识别和关系抽取的奇妙之旅
探索图像数据中的隐藏信息:语义实体识别和关系抽取的奇妙之旅 1. 简介 1.1 背景 关键信息抽取 (Key Information Extraction, KIE)指的是是从文本或者图像中,抽取出关键的信息。针对文档图像的关键信息抽取任务作为OCR的下游任务,存在非常…...
Gradle问题处理
目录 一、依赖搜索问题1.1 、Gradle不在本地 Maven 存储库中进行搜索一、依赖搜索问题 1.1 、Gradle不在本地 Maven 存储库中进行搜索 场景 build.gradle文件: buildscript {repositories {mavenLocal()google()mavenCentral()}dependencies...
架构:C4 Model
概念 C4说穿了就是几个要素:关系——带箭头的线、元素——方块和角色、关系描述——线上的文字、元素的描述——方块和角色里的文字、元素的标记——方块和角色的颜色、虚线框(在C4里面虚线框的表达力被极大的限制了,我觉得可以给虚线框更大…...
数据结构学习系列之顺序表的两种修改方式
方式1:根据顺序表中数据元素的位置进行修改,代码如下:示例代码: int modify_seq_list_1(list_t *seq_list,int pos, int data){if(NULL seq_list){printf("入参为NULL\n");return -1;}if( pos < 0 || pos > seq…...
React:props说明
props是只读对象(readonly) 根据单项数据流的要求,子组件只能读取props中的数据,不能进行修改props可以传递任意数据 数字、字符串、布尔值、数组、对象、函数、JSX import FileUpdate from ./FileUpdate; export default class …...

Can‘t connect to local MySQL server through socket ‘/tmp/mysql.sock‘
最近在用django框架开发后端时,在运行 $python manage.py makemigrations 命令时,报了以上错误,错误显示连接mysql数据库失败,查看了mysql数据库初始化配置文件my.cnf,我的mysql.sock文件存放路径配置在了/usr/local…...
C++的单例模式
忘记之前有没有写过单例模式了。 再记录一下: 我使用的代码: #ifndef SINGLETON_MACRO_HPP #define SINGLETON_MACRO_HPP#define SINGLETON_DECL(class_name) \ public: \static class_name& instance() { \static class_name s_instance; \return …...

Spring Boot 中 Nacos 配置中心使用实战
官方参考文档 https://nacos.io/zh-cn/docs/quick-start-spring-boot.html 本人实践 1、新建一个spring boot项目 我的spirngboot版本为2.5.6 2、添加一下依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-…...

学生管理系统VueAjax版本
学生管理系统VueAjax版本 使用Vue和Ajax对原有学生管理系统进行优化 1.准备工作 创建AjaxResult类,对Ajax回传的信息封装在对象中 package com.grg.Result;/*** Author Grg* Date 2023/8/30 8:51* PackageName:com.grg.Result* ClassName: AjaxResult* Descript…...
迭代器模式简介
概念: 迭代器模式是一种行为型设计模式,它提供了一种访问集合对象元素的方法,而无需暴露其内部表示。通过使用迭代器,可以按照特定顺序遍历集合中的元素。 特点: 将遍历和具体集合分离,使得能够独立地改…...
四方定理c++题解
题目描述 四方定理是数论中著名的一个定理,指任意一个自然数都可以拆成四个自然数的平方之和。例如: 251^22^22^24^2 对 25来说,还有其他方案: 250^20^23^24^2 以及 250^20^20^25^2 给定一个自然数 n ,请输出 n…...

ZDH-权限模块
本次介绍基于ZDH v5.1.2版本 目录 项目源码 预览地址 安装包下载地址 ZDH权限模块 ZDH权限模块-重要名词划分 ZDH权限模块-菜单管理 ZDH权限模块-角色管理 ZDH权限模块-用户配置 ZDH权限模块-权限申请 项目源码 zdh_web: GitHub - zhaoyachao/zdh_web: 大数据采集,抽…...

漏洞修复:在应用程序中发现不必要的 Http 响应头
描述 blablabla描述,一般是在返回的响应表头中出现了Server键值对,那我们要做的就是移除它,解决方案中提供了nginx的解决方案 解决方案 第一种解决方案 当前解决方案会隐藏nginx的版本号,但还是会返回nginx字样,如…...

什么是mkp勒索病毒,中了mkp勒索病毒怎么办?勒索病毒解密数据恢复
mkp勒索病毒是一种新兴的计算机木马病毒,它以加密文件的方式进行勒索,对用户的计算机安全造成了严重威胁。本文将介绍mkp勒索病毒的特征、影响以及应对措施,以便读者更好地了解和防范这种病毒。 一、mkp勒索病毒的特征 加密文件:…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...