设计模式-装饰器模式(结构型)与责任链模式(行为型)对比,以及链式设计
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 1.装饰器模式
- 1.1概念
- 1.2作用
- 1.3应用场景
- 1.4特点
- 1.5类与对象关系
- 1.6实现
- 2责任链模式
- 2.1概念
- 2.2作用
- 2.3应用场景
- 2.4特点
- 2.5类与对象关系
- 2.6实现
- 3.对比
- 总结
前言
装饰器模式和设计模式同为GoF23中设计模式之一,两者在结构上有相似之处,本文章用来学习两个设计模式,并进行对比。
1.装饰器模式
1.1概念
如果我们想要为一个已经写好的类增加新功能,在不修改该类源码的情况下,我们有以下选择:
- 创建该类的子类,并用该子类调用父类方法,并额外添加其他功能
- 创建一个新的类,引用已有类的对象,调用原有方法并添加其他功能
这里第二种实现思路就是我们现在说的装饰器模式。
1.2作用
为一个已有的类增加新的功能。
1.3应用场景
- 需要动态地给对象添加职责时:当你需要给某个对象添加职责,但又不想修改其类定义时,可以使用装饰器模式。
- 需要灵活组合多个职责时:当你有多个职责需要组合,并且这些职责的排列组合可能会变化时,装饰器模式是一个很好的选择。
- 需要保持类的单一职责原则时:当你想保持类的单一职责原则,但又需要给类添加额外的职责时,可以使用装饰器模式将这些职责分离到装饰器中
1.4特点
- 动态扩展:装饰器模式能够在运行时动态地给对象添加职责,而无需修改类的定义。
- 灵活性:通过组合的方式而不是继承来扩展功能,这使得装饰器模式比继承更加灵活。
- 遵循开闭原则:装饰器模式可以在不修改现有代码的情况下添加新的功能,符合开闭原则(对扩展开放,对修改关闭)。
- 装饰器与被装饰对象拥有相同的接口:这使得装饰器可以透明地替代被装饰对象
1.5类与对象关系
- 组件接口:对应上图Component,用来规定被装饰对象和装饰器应该有哪些功能(或者说原组件中哪些功能是可以装饰的)
- 组件类:对应上图ConcreteComponent,是被装饰对象
- 抽象装饰器:对应上图Decorator,是一个接口,因为我们会有多个不同的具体装饰器,所以需要使用一个抽象装饰器接口来指定具体装饰器应该有哪些功能
- 具体装饰器:是我们真正的额外功能编写的地方,因为实现了抽象装饰器所以拥有与被装饰对象相同但更强大的功能,可以在使用时进行替换。
1.6实现
// 定义一个接口,规定哪些方法可以被装饰
interface Component {void operation();
}// 具体组件类,实现了Component接口
class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("ConcreteComponent operation");}
}// 抽象装饰器类,持有一个Component对象,并实现了Component接口
abstract class Decorator implements Component {// 该对象存储原对象或者被其他装饰器装饰过的对象// 因为可以是其他装饰器装饰过的对象,所以才实现装饰器的叠加,是动态添加功能的关键protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}// 具体装饰器类A,增加了额外的行为
class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operation() {super.operation();addedBehavior();}private void addedBehavior() {System.out.println("ConcreteDecoratorA added behavior");}
}// 具体装饰器类B,增加了额外的行为
class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}@Overridepublic void operation() {addedBehavior();super.operation();}private void addedBehavior() {System.out.println("ConcreteDecoratorB added behavior");}
}// 客户端代码
public class DecoratorPatternDemo {public static void main(String[] args) {Component component = new ConcreteComponent();// 使用装饰器A装饰Component decoratorA = new ConcreteDecoratorA(component);// 使用装饰器B装饰装饰器AComponent decoratorB = new ConcreteDecoratorB(decoratorA);// 执行操作,将展示所有组件和装饰器的行为decoratorB.operation();}
}
2责任链模式
2.1概念
责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行传递。每个处理者可以对请求进行处理,或者将请求传递给链中的下一个处理者。这使得你可以在不明确具体接收者的情况下,向多个对象发送请求。
2.2作用
- 解耦请求与处理:请求者只要向链头发送一次请求,而不用关心具体由谁处理。
- 可以动态管理处理类:可以按需添加或删除处理类。
2.3应用场景
- 多个对象有机会处理请求:当请求可以在多个对象之间传递,并且每个对象都有可能处理它时。
- 请求处理顺序可变:当请求的处理顺序不固定,或者你想在不修改代码的情况下改变处理顺序时。
- 解耦请求发送者和处理者:当你想解耦请求发送者和处理者之间的依赖关系时。
2.4特点
- 链式传递:请求在多个处理者之间传递,直到有一个处理者处理它或链结束。
- 解耦请求发送者和接收者:发送者不需要知道哪个具体的处理者会处理请求,它只需要将请求发送到链的头部即可。
- 增强灵活性:你可以通过动态地添加或删除处理者来改变链的结构,从而改变请求的处理流程。
2.5类与对象关系
责任链模式中我们有以下角色:
- 抽象处理者(Handler)角色:声明“处理”方法,以及一个“设置下一处理器”的方法
- 具体处理者(Concrete Handler)角色:实现了抽象处理者接口,并包含处理请求的逻辑。如果它不能处理请求,它会将请求传递给链中的下一个处理者。
2.6实现
// 抽象处理者接口
abstract class Handler {protected Handler nextHandler;// 设置下一个处理者public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}// 处理请求的方法,由具体处理者实现public abstract void handleRequest(String request);
}// 具体处理者类A
class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(String request) {if ("A".equals(request)) {System.out.println("ConcreteHandlerA handled request: " + request);} else {if (nextHandler != null) {nextHandler.handleRequest(request);}}}
}// 具体处理者类B
class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(String request) {if ("B".equals(request)) {System.out.println("ConcreteHandlerB handled request: " + request);} else {if (nextHandler != null) {nextHandler.handleRequest(request);}}}
}// 客户端代码
public class ChainOfResponsibilityDemo {public static void main(String[] args) {// 创建处理者对象Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();// 构建处理者链handlerA.setNextHandler(handlerB);// 创建并发送请求String[] requests = {"A", "B", "C"};for (String request : requests) {handlerA.handleRequest(request); // 请求从handlerA开始传递}}
}
3.对比
- 首先,链式设计最重要的一点是——一个节点中要存储相邻节点的信息,这一点在上述两种设计模式中都有体现。这里要先清楚各自具体存储的是什么。
- 装饰器模式存储的是原组件或被修饰过的组件,这说明在该种模式下各个装饰器的作用是可以叠加的
- 责任链模式存储的是下一个处理节点,这里各个处理器效果并不会叠加
- 其次,各个节点应该有同样的任务。这两种模式中不论是各个装饰器,还是各个处理器,其实都有同样的任务。但是两个模式在具体实现时有区别,这也是装饰器模式可叠加而责任链模式不可叠加的原因。
- 装饰器中的方法逻辑是——上一节点处理逻辑"及"本节点处理逻辑
- 责任链中的方法逻辑是——本节点处理逻辑"或"下节点处理逻辑
总结
本文章比较了装饰器模式和责任链模式,因为两者在结构上十分相似都使用了链式设计,所以容易混淆,这里需要重点理解两者在处理方法中的实现逻辑的不同,装饰器是"且",责任链是"或"。
相关文章:
设计模式-装饰器模式(结构型)与责任链模式(行为型)对比,以及链式设计
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1.装饰器模式1.1概念1.2作用1.3应用场景1.4特点1.5类与对象关系1.6实现 2责任链模式2.1概念2.2作用2.3应用场景2.4特点2.5类与对象关系2.6实现 3.对比总结 前言…...
outlook软件配置邮箱提示“到邮件服务器的加密连接不可用”
outlook软件配置邮箱提示“到邮件服务器的加密连接不可用” 问题描述: outlook软件里邮箱提示“已断开”或配置邮箱时提示“到邮件服务器的加密连接不可用”。 解决方案: 一、更改注册表(可先导出备份) winr,输入re…...
通过QT实现进度条随着读取文件增加
mythread循环给主线程发送信号实现主线程循环的功能 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QFile> #include <QFileDialog> #include <QTextStream> #include <QByteArray> #include "mythread.h"…...
构建高效可靠的分布式推理系统:深入解析控制器与模型服务的协同工作
在现代互联网应用中,随着用户需求的增长和技术的进步,单一服务器已经难以满足大规模并发请求的需求。为了提升系统的性能和可靠性,开发者们越来越多地采用分布式架构。本文将结合具体的代码示例,深入浅出地探讨如何构建一个高效的分布式推理系统,并详细解析其中的关键组件…...
洛谷B2082
数字统计 - 洛谷 数字统计 题目描述 请统计某个给定范围 [L,R] 的所有整数中,数字 2 出现的次数。 比如给定范围 [2,22],数字2 在数 2 中出现了 1 次,在数 12 中出现 1 次,在数 20中出现 1次,在数 21 中出现 1 次&…...
HTML5系列(14)-- 链接与资源关系指南
前端技术探索系列:HTML5 链接与资源关系指南 🔗 致读者:探索资源加载的艺术 👋 前端开发者们, 今天我们将深入探讨 HTML5 的链接与资源关系管理,学习如何优化网站的资源加载策略,提升用户体验…...
ubuntu系统每天凌晨定时上传redis 备份数据到阿里云OSS上
1.压缩备份脚本 1.1 代码如下#!/bin/bash# redis_backup_compress.sh # 设置变量 BACKUP_DIR"/data/redis/backup" REDIS_DIR"/var/lib/redis" DATE$(date %Y%m%d_%H%M%S) BACKUP_FILE"redis_backup_${DATE}.rdb" COMPRESSED_FILE"redis_b…...
uniapp结合movable-area与movable-view实现拖拽功能
前言 因为公司业务开发需要拖拽功能。 ps:该功能只能针对高度一致的,如果高度不一致需要另外二开 演示 开始 <template><view style"height: 100%;"><movable-area :style"{width: 100%, height: allHeight px}"…...
JavaScript 单例模式的创建与应用
JavaScript 单例模式的创建与应用 单例模式(Singleton Pattern)是一种设计模式,旨在确保一个类只有一个实例,并提供全局访问点。在 JavaScript 中,单例模式可以帮助我们避免多次创建同一个对象,节省资源&a…...
【HarmonyOS】 鸿蒙保存图片或视频到相册
【HarmonyOS】 鸿蒙保存图片或视频到相册 前言 鸿蒙中保存图片或者视频,或者其他媒体文件到设备的媒体库,可以是相册,也可以是文件管理等。共有两种方式: 需要应用申请受限权限,获取文件读写的权限(调用…...
windows下nacos启动报错:java.lang.unsatisfiedLinkError: C:\USers\乱码AppData\xxx.dll
问题 看了许多别的帖子,大家都是因为缺少dll包,下载安装 Microsoft Visual C 2015 Redistributable 就可以。但我试过了不行。思来想去,之前正常的时候用的JDK版本是17,后面别的项目用1.8给切换回来了。然后尝试配置环境变量将JD…...
梳理你的思路(从OOP到架构设计)_基本OOP知识01
目录 1、“-Oriented” 的涵意 2、 ” -Oriented”、” -Based”、” -Driven”、” -Centered” 它们之间区别 3、 从对象(Object) 谈起 4、类的用途: 叙述软件对象 Android从程序员到架构师之路:梳理你的思路(从OOP到架构设计) 1、“-Oriented” …...
【C++图论 BFS算法】2467. 树上最大得分和路径|2053
本文涉及知识点 C图论 CBFS算法 LeetCode2467. 树上最大得分和路径 一个 n 个节点的无向树,节点编号为 0 到 n - 1 ,树的根结点是 0 号节点。给你一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] [ai, bi] ,表示节点 a…...
Java的Mvc整合Swagger的knife4框架
Swagger的介绍 Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。使用Swagger,就是把相关的信息存储在它定义的描述文件里面(yml或json格式),再通过维护这个描述 文件可以去更…...
AI项目二十六:YOLOV11简单部署测试
若该文为原创文章,转载请注明原文出处。 一、YOLOv11介绍 继YOLOv 8、YOLOv 9和YOLOv10之后,发布的YOLOV11引入了几个突破性的增强功能,为目标检测和计算机视觉设定了新的基准。 增强的特征提取:YOLOv11使用改进的主干和颈部架构…...
19. Three.js案例-创建一个带有纹理映射的旋转平面
19. Three.js案例-创建一个带有纹理映射的旋转平面 实现效果 知识点 WebGLRenderer (WebGL渲染器) WebGLRenderer 是 Three.js 中用于渲染场景的主要类。它利用 WebGL 技术在浏览器中绘制 3D 图形。 构造器 new THREE.WebGLRenderer(parameters)参数类型描述parametersobj…...
【Makefile】编译日志之输出重定向符号 >
用法1 make all >& compilelog.txt make all > compilelog.txt这两个编译命令在功能上有一些细微的区别,主要在于标准输出和标准错误的处理方式。 make all >& compilelog.txt 这个命令会将标准输出(stdout)和标准错误&a…...
TDengine 新功能 复合主键
1. 简介 从 TDengine 3.3.0.0 版本之后,新增了复合主键的功能。 TDengine 原来的时间列是不允许有重复时间戳的,有了复合主键功能后,时间列即允许有重复,重复后的时间戳按紧跟其后第二列主键列的值来确定唯一性。 此功能的常用…...
【OpenHarmony】初识设备间互联互通的统一基础:分布式软总线
分布式软总线 前言软总线软总线代码目录软总线传输模块概述传输模块主要对外接口和使用方式 前言 很久没有写出一篇能够分享出来的学习心得了,零零散散地写了好多,总是不太满意。今年8月份开始正式投入精力去学习open harmony,记得第一次接触…...
yocto加软件包install 动态链接库报错
加入bb文件,编译通过 在install时报错 报错 ERROR: demo-1.0-r0 do_package_qa: QA Issue: -dev package agent-dev contains non-symlink .so ‘/usr/lib64/libdemo.so’ 解决 在bb文件install前加2行 SOLIBS ".so" FILES_SOLIBSDEV ""do_install …...
《数据结构》(408代码题)
2009 单链表(双指针) 分析:首先呢,给我们的数据结构是一个带有表头结点的单链表,也不允许我们改变链表的结构。链表的长度不是直接给出的啊,所以这个倒数也很棘手。那我们该如何解决这个“k”呢,…...
哈希表的完善及unordered_map/unordered_set封装
1.哈希表的完善 1.1 优化:哈希函数 在实际使用中,往往需要以字符串作为存储依据(键值),比如姓名与快递信息、商品名称与价格、中文单词与英文释义等。 而在上一篇文章中,我们实现的哈希表只考虑了整型的存储情况,即直…...
“物联·数据·产融·场景”聚力垂直数智场景下的新质生产力破局
人工智能、物联网(简称AIOT)正在深刻改变世界的经济格局,对各行各业产生深厚的影响。12月6日,由深圳市物联网协会、华夏银行深圳分行、深圳市区块链技术应用协会、深圳市康复辅助器具智能技术应用协会联合主办的第五届AIOT生态大会…...
API接口的性能测试与优化策略
在现代软件开发中,API(应用程序编程接口)扮演着至关重要的角色,它们作为不同服务之间的桥梁,确保数据的顺畅流通与交互。然而,随着用户需求的不断增长和系统复杂性的提升,API接口的性能问题日益…...
【Vue】Part4 接口调用
接口调用方式 原生ajax基于jQuery的ajaxfetchaxios 异步 JavaScript的执行环境是「单线程」所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,…...
管理系统前端框架开发案例学习
一、 需求分析 本案例的主要目标是开发一个智能学习辅助系统的前端界面,涵盖以下功能模块: 首页:显示系统的总体概览和关键功能介绍。 班级学员管理:实现班级管理和学员管理。 系统信息管理:管理部门和员工信息。 …...
协程设计原理与实现
协程设计原理与汇编实现 同步与异步 对于任何一个事情,都可以划分为不同的步骤。所谓同步,就先做第一个事情,按照这件事的步骤完成这件事之后,再去做第二件事。再去做第三件事,以此类推。 异步就是,可以…...
c++广播通讯的实现
概念大家都很清楚,不赘述。 广播必然用UDP这套东西。 setsockopt() 函数及其在广播中的应用: 在 C 网络编程中,setsockopt() 函数用于设置套接字选项,这些选项可以控制套接字的各种行为。对于广播通信,我们特别关心…...
Leetcode 3377. Digit Operations to Make Two Integers Equal
Leetcode 3377. Digit Operations to Make Two Integers Equal 1. 解题思路2. 代码实现 题目链接:3377. Digit Operations to Make Two Integers Equal 1. 解题思路 这一题的核心思路属于路径遍历问题,我们使用一个堆排来控制最优路径的选择。 我们首…...
高项 - 项目管理原则与项目绩效域
个人总结,仅供参考,欢迎加好友一起讨论 博文更新参考时间点:2024-12 高项 - 章节与知识点汇总:点击跳转 文章目录 高项 - 项目管理原则与项目绩效域项目管理12条原则原则1:成为勤勉、尊重和关心他人的管家 (p202)原则…...
【开源】A065—基于SpringBoot的库存管理系统的设计与实现
🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看项目链接获取⬇️,记得注明来意哦~🌹 赠送计算机毕业设计600个选题ex…...
LeetCode—189. 轮转数组(中等)
题目描述: 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例1: 输入: nums [1,2,3,4,5,6,7], k 3输出:[5,6,7,1,2,3,4] 解释: 向右轮转 1 步:[7,1,2,3,4,5,6] 向右轮转 2 步:[6,7,1,2,3,4,5] 向…...
fastadmin框架同时使用 阿里云oss和阿里云点播
背景 项目的实际需求中既要用到阿里云oss产品又用到阿里云点播系统,实现完美的统一。设置两个地址downUrl,thirdCode。分别代表阿里云oss上传路径和阿里云点播系统vId。 实现 默认框架你已经集成好阿里云oss集成工作,前端html页面实现 <…...
MySQL-DML之数据表操作
文章目录 一. 插入表记录1. 向表中插入部分字段2. 向表中插入所有字段,字段的顺序为创建表时的顺序3. 一次添加多条数据信息 二. 更新表记录1. 更新所有记录的指定字段 更新符号条件记录的指定字段2. 更新符号条件记录的指定字段 三. 删除表记录1. 按条件删除记录2. 清空记录 四…...
Android 逆向/反编译/Hook修改应用行为 基础实现
前言:本文通过一个简单的情景案例实现安卓逆向的基本操作 一、情景描述 本文通过一个简单的情景案例来实现安卓逆向的基本操作。在这个案例中所使用的项目程序是我自己的Demo程序,不会造成任何的财产侵害,本文仅作为日常记录及案例分享。实…...
【前端】理解 JavaScript 对象属性访问的复杂性
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 💯前言💯理论基础:JavaScript 对象属性的访问模式1. 点符号访问(Dot Notation)2. 方括号访问(Bracket Notation)点符号…...
进入 Dystopia:第九周游戏指南
本指南将为大家详细说明在第八周的每个体验中可以获得的奖励。 在杂草丛生的反乌托邦废墟中生存,随着大自然重新开垦这片土地,文明已陷入绝望。穿越高耸入云、摇摇欲坠的摩天大楼,抵御末世社会的各种危险。适应这个文明与荒野之间的界限已经消…...
Helm安装Mysql8主从复制集群
目录 一、Helm安装 二、安装mysql 1、拉取镜像 2、修改配置文件 3、创建mysql-secret 4、安装 一、Helm安装 这里不再赘叙,具体安装请参考官网 Helm | 快速入门指南 二、安装mysql 1、拉取镜像 #添加仓库 helm repo add bitnami https://charts.bitnami.c…...
[小白系列]GPU-nvidia-smi指令
nvidia-smi(NVIDIA System Management Interface)是一种命令行实用程序,用于监控和管理NVIDIA GPU(图形处理器)的状态和性能。它提供了一种简单而强大的方式来获取有关GPU的实时信息,并且可以用于诊断、…...
Flutter 图片编辑板(一) 事件路由
一个图片编辑板,有两部分组成。编辑板和内容项。每一个内容项是被InteractiveViewer修饰的widget,具有缩放偏移的功能。 在图片编辑板上, 会有多个内容相,图片或文字(添加文字目前还没做过)。 当要编辑其中…...
Cherno C++学习笔记 P33 字符串的字面量
在这篇文章当中我们介绍一下有关于字符串更加深入的知识,也就是字符串的字面量。 首先什么是字面量?其实也很简单,就是双引号里面的那一坨,其实就是字面量,我们举一个最简单的例子: #include<iostream…...
数据结构 (36)各种排序方法的综合比较
一、常见排序方法分类 插入排序类 直接插入排序:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。希尔排序:是插入排序的一种改进版本,先将整个待排序的记录序列分割成为…...
Master EDI 项目需求分析
Master Electronics 通过其全球分销网络,支持多种采购需求,确保能够为客户提供可靠的元件供应链解决方案,同时为快速高效的与全球伙伴建立合作,Master 选择通过EDI来实现与交易伙伴间的数据传输。 EDI为交易伙伴之间建立了一个安…...
java+ssm+mysql计算机等级考试网
项目介绍: 使用javassmmysql开发的计算机等级考试信息网,系统包含前后台,包含超级管理员,系统管理员角色,功能如下: 前台:首页;考试动态;相关资源下载;考试…...
MitelMiCollab 身份绕过导致任意文件读取漏洞复现(CVE-2024-41713)
0x01 产品描述: Mitel MiCollab 是一个企业协作平台,它将各种通信工具整合到一个应用程序中,提供语音和视频通话、消息传递、状态信息、音频会议、移动支持和团队协作功能。0x02 漏洞描述: Mitel MiCollab 的 NuPoint 统一消息 (NPM) 组件中存在身份验证绕过漏洞,由于输入…...
【Python]深入Python日志管理:从logging到分布式日志追踪的完整指南
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 日志是软件开发中的核心部分,尤其在分布式系统中,日志对于调试和问题定位至关重要。本篇文章将从Python标准库的logging模块出发,逐步探讨日志管理的最佳实践,涵盖日志配置、日志分层、日志格式化等基…...
python rstrip 的迷惑行为
在项目中,我需要把字符串末尾的一部分去掉,类似截断,我用ide的随笔提示,发现了rstrip这个方法,然后我试了下,满足我的需求,但在测试过程中,我发现了rstrip的一些行为很让我迷惑。 开…...
SPI通信协议
SPI通信协议 简介通信原理通信原理SPI数据通信的流程可以分为以下几步:通信特性设备时钟时钟速率时钟极性跟相位SPI协议层通讯流程详解优点:缺点: DS1302 时钟实验控制寄存器日历、时钟寄存器寄存器说明 DS1302 读写时序软件功能实现 简介 SP…...
vue中如何实现商品多规格添加(后台商城管理系统)
在制作商城类的后台管理系统中会遇到多规格商品的添加,需要向固定的数组内添加,通过查看数据结构正确的向数组中添加数据。 如图: 功能需求:1.每次点击添加新规格时,批量设置会多出来一行表格和一个标题输入框。 最…...
智创 AI 新视界 -- AIGC 重塑广告行业的创新力量(16 - 7)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...