Python设计模式:命令模式
1. 什么是命令模式?
命令模式是一种行为设计模式,它将请求封装为一个对象,从而使您能够使用不同的请求、队列或日志请求,以及支持可撤销操作。
命令模式的核心思想是将请求的发送者与请求的接收者解耦,使得两者之间的交互更加灵活。
1.1 命令模式的组成部分
命令模式通常包含以下几个组成部分,每个部分都有其特定的角色和功能。下面将详细介绍每个组成部分,并提供相应的代码示例。
1.1.1 命令接口(Command Interface)
命令接口定义了一个执行操作的接口,通常包含一个 execute
方法。所有具体命令类都需要实现这个接口。
# 命令接口
class Command:def execute(self):pass
1.1.2 具体命令类(Concrete Command)
具体命令类实现命令接口,定义与接收者之间的绑定关系,并调用接收者的相应操作。每个具体命令类都对应一个特定的操作。
# 接收者
class Light:def turn_on(self):print("The light is ON")def turn_off(self):print("The light is OFF")# 具体命令类
class LightOnCommand(Command):def __init__(self, light):self.light = lightdef execute(self):self.light.turn_on()class LightOffCommand(Command):def __init__(self, light):self.light = lightdef execute(self):self.light.turn_off()
1.1.3 接收者(Receiver)
接收者是具体的业务逻辑类,包含实际执行操作的方法。命令对象会调用接收者的方法来完成请求。
class Light:def turn_on(self):print("The light is ON")def turn_off(self):print("The light is OFF")
1.1.4 调用者(Invoker)
调用者持有命令对象并在适当的时候调用命令的 execute
方法。调用者不需要知道命令的具体实现,只需调用命令接口。
示例代码
class RemoteControl:def __init__(self):self.command = Nonedef set_command(self, command):self.command = commanddef press_button(self):if self.command:self.command.execute()
1.1.5 客户端(Client)
客户端负责创建具体命令对象并设置接收者。客户端代码通常会将命令对象传递给调用者。
if __name__ == "__main__":# 创建接收者light = Light()# 创建具体命令light_on = LightOnCommand(light)light_off = LightOffCommand(light)# 创建调用者remote = RemoteControl()# 开灯remote.set_command(light_on)remote.press_button() # 输出: The light is ON# 关灯remote.set_command(light_off)remote.press_button() # 输出: The light is OFF
-
命令接口:定义了一个命令接口
Command
,包含一个execute
方法,所有具体命令类都需要实现这个方法。 -
具体命令类:
LightOnCommand
和LightOffCommand
实现了命令接口,分别用于打开和关闭灯。它们持有一个Light
对象的引用,并在execute
方法中调用相应的接收者方法。 -
接收者:
Light
类是接收者,包含实际执行操作的方法turn_on
和turn_off
。 -
调用者:
RemoteControl
类持有命令对象,并在适当的时候调用命令的execute
方法。它提供了set_command
方法来设置命令对象。 -
客户端代码:在客户端代码中,创建接收者、具体命令和调用者,并通过调用者执行命令。客户端代码不需要知道命令的具体实现,只需使用命令接口。
1.2 命令模式的优点
1.2.1 解耦
说明:命令模式通过将请求的发送者与接收者解耦,使得发送者不需要知道接收者的具体实现。这种解耦使得系统更加灵活,便于维护和扩展。
1. 灵活性:发送者可以在不修改代码的情况下替换接收者。
# 接收者
class Light:def turn_on(self):print("The light is ON")def turn_off(self):print("The light is OFF")# 具体命令类
class LightOnCommand(Command):def __init__(self, light):self.light = lightdef execute(self):self.light.turn_on()# 新的接收者
class Fan:def turn_on(self):print("The fan is ON")def turn_off(self):print("The fan is OFF")# 客户端代码
light = Light()
fan = Fan()light_on_command = LightOnCommand(light)
light_on_command.execute() # 输出: The light is ON# 替换接收者
fan_on_command = LightOnCommand(fan) # 这里可以直接替换为 Fan
fan_on_command.execute() # 输出: The fan is ON
2. 可维护性:修改接收者的实现不会影响发送者。
# 修改接收者的实现
class Light:def turn_on(self):print("The light is now ON")# 客户端代码
light = Light()
light_on_command = LightOnCommand(light)
light_on_command.execute() # 输出: The light is now ON
3. 可扩展性:轻松添加新命令而不修改现有代码。
# 新的具体命令类
class LightOffCommand(Command):def __init__(self, light):self.light = lightdef execute(self):self.light.turn_off()# 客户端代码
light_off_command = LightOffCommand(light)
light_off_command.execute() # 输出: The light is OFF
4. 支持多种请求:可以处理不同类型的请求。
# 另一个具体命令类
class FanOnCommand(Command):def __init__(self, fan):self.fan = fandef execute(self):self.fan.turn_on()# 客户端代码
fan_on_command = FanOnCommand(fan)
fan_on_command.execute() # 输出: The fan is ON
如果不采用解耦的设计,可能会面临以下风险:
1. 紧耦合:请求的发送者和接收者之间的紧耦合关系。
# 紧耦合示例
class RemoteControl:def __init__(self):self.light = Light() # 直接依赖于具体的接收者def turn_on_light(self):self.light.turn_on()# 客户端代码
remote = RemoteControl()
remote.turn_on_light() # 输出: The light is ON
2. 难以扩展:添加新功能需要修改现有代码。
# 添加新功能需要修改现有代码
class RemoteControl:def __init__(self):self.light = Light()self.fan = Fan() # 需要修改代码以添加新功能def turn_on_light(self):self.light.turn_on()def turn_on_fan(self):self.fan.turn_on()# 客户端代码
remote = RemoteControl()
remote.turn_on_fan() # 输出: The fan is ON
1.2.2 可扩展性
说明:可以轻松添加新的命令,而不需要修改现有代码。只需创建新的命令类并实现命令接口即可。
示例代码
# 新的具体命令类
class FanOffCommand(Command):def __init__(self, fan):self.fan = fandef execute(self):self.fan.turn_off()# 客户端代码
fan_off_command = FanOffCommand(fan)
fan_off_command.execute() # 输出: The fan is OFF
1.2.3 支持撤销操作
说明:可以通过维护命令的历史记录来实现撤销操作。每个命令对象可以记录其执行的状态,以便在需要时进行撤销。
示例代码
class CommandHistory:def __init__(self):self.history = []def push(self, command):self.history.append(command)def pop(self):if self.history:return self.history.pop()return None# 客户端代码
history = CommandHistory()# 执行命令
history.push(light_on_command)
light_on_command.execute() # 输出: The light is ON# 撤销命令
last_command = history.pop()
if last_command:print("Undoing last command...")# 这里可以实现撤销逻辑,例如不绘制图形
1.2.4 支持队列请求
说明:可以将请求放入队列中,按顺序执行。这使得命令模式非常适合处理异步请求或批量操作。
示例代码
from collections import dequeclass CommandQueue:def __init__(self):self.queue = deque()def add_command(self, command):self.queue.append(command)def execute_commands(self):while self.queue:command = self.queue.popleft()command.execute()# 客户端代码
command_queue = CommandQueue()
command_queue.add_command(light_on_command)
command_queue.add_command(fan_on_command)# 执行所有命令
command_queue.execute_commands()
# 输出:
# The light is ON
# The fan is ON
2. 示例 1:命令模式在文本编辑器中的应用
命令模式是一种强大的设计模式,能够有效地解耦请求的发送者与接收者,提高代码的灵活性和可维护性。在本文中,我们将通过一个文本编辑器的示例,展示如何使用命令模式来实现文本操作(如插入、删除和撤销)。
# 命令接口
class Command:def execute(self):passdef undo(self):pass# 接收者
class TextEditor:def __init__(self):self.text = ""def insert(self, text):self.text += textprint(f"Inserted: '{text}' | Current text: '{self.text}'")def delete(self, length):deleted_text = self.text[-length:] if length <= len(self.text) else self.textself.text = self.text[:-length]print(f"Deleted: '{deleted_text}' | Current text: '{self.text}'")# 具体命令类
class InsertCommand(Command):def __init__(self, editor, text):self.editor = editorself.text = textdef execute(self):self.editor.insert(self.text)def undo(self):self.editor.delete(len(self.text))class DeleteCommand(Command):def __init__(self, editor, length):self.editor = editorself.length = lengthself.deleted_text = ""def execute(self):self.deleted_text = self.editor.text[-self.length:] if self.length <= len(self.editor.text) else self.editor.textself.editor.delete(self.length)def undo(self):self.editor.insert(self.deleted_text)# 调用者
class CommandHistory:def __init__(self):self.history = []def push(self, command):self.history.append(command)def pop(self):if self.history:return self.history.pop()return Noneclass CommandQueue:def __init__(self):self.queue = []def add_command(self, command):self.queue.append(command)def execute_commands(self, history):while self.queue:command = self.queue.pop(0)command.execute()history.push(command) # 将执行的命令添加到历史记录中# 客户端代码
if __name__ == "__main__":# 创建接收者editor = TextEditor()history = CommandHistory()command_queue = CommandQueue()# 创建并执行插入命令print("Executing insert commands:")insert_command1 = InsertCommand(editor, "Hello, ")command_queue.add_command(insert_command1)insert_command2 = InsertCommand(editor, "World!")command_queue.add_command(insert_command2)# 执行所有命令并记录到历史command_queue.execute_commands(history)# 预期输出: "Inserted: 'Hello, ' | Current text: 'Hello, '"# 预期输出: "Inserted: 'World!' | Current text: 'Hello, World!'"print(f"Current text after insertions: '{editor.text}'") # 输出: Hello, World!# 撤销最后一个命令(插入)print("\nUndoing last insert command:")last_command = history.pop()if last_command:last_command.undo() # 撤销插入操作# 预期输出: "Deleted: 'World!' | Current text: 'Hello, '"print(f"Current text after undo: '{editor.text}'") # 输出: Hello,# 创建并执行删除命令print("\nExecuting delete command:")delete_command = DeleteCommand(editor, 6)command_queue.add_command(delete_command)command_queue.execute_commands(history)# 预期输出: "Deleted: 'Hello, ' | Current text: ''"print(f"Current text after deletion: '{editor.text}'") # 输出: (空字符串)# 撤销删除命令print("\nUndoing delete command:")last_command = history.pop()if last_command:last_command.undo() # 撤销删除操作# 预期输出: "Inserted: 'Hello, ' | Current text: 'Hello, '"print(f"Current text after undo delete: '{editor.text}'") # 输出: Hello,# 最终状态print(f"\nFinal text: '{editor.text}'") # 输出最终文本状态
Executing insert commands:
Inserted: 'Hello, ' | Current text: 'Hello, '
Inserted: 'World!' | Current text: 'Hello, World!'
Current text after insertions: 'Hello, World!'Undoing last insert command:
Deleted: 'World!' | Current text: 'Hello, '
Current text after undo: 'Hello, 'Executing delete command:
Deleted: 'ello, ' | Current text: 'H'
Current text after deletion: 'H'Undoing delete command:
Inserted: 'ello, ' | Current text: 'Hello, '
Current text after undo delete: 'Hello, 'Final text: 'Hello, '
-
命令接口:定义了一个命令接口
Command
,包含execute
和undo
方法。所有具体命令类都需要实现这两个方法。 -
接收者:
TextEditor
类是接收者,包含实际执行操作的方法insert
和delete
。这些方法负责修改文本状态并输出当前文本。 -
具体命令类:
InsertCommand
用于插入文本。它持有一个TextEditor
对象的引用,并在execute
方法中调用insert
方法。在undo
方法中调用delete
方法以撤销插入操作。DeleteCommand
用于删除文本。它同样持有一个TextEditor
对象的引用,并在execute
方法中调用delete
方法。在undo
方法中调用insert
方法以撤销删除操作。
-
调用者:
CommandHistory
类用于维护命令的历史记录,以支持撤销操作。它提供push
和pop
方法来管理命令历史。CommandQueue
类用于将命令放入队列中,按顺序执行,并在执行时将命令添加到历史记录中。
-
客户端代码:在客户端代码中,创建接收者、具体命令和调用者,并通过调用者执行命令。每个执行的命令都会被记录到
CommandHistory
中,以便后续撤销。
相关文章:
Python设计模式:命令模式
1. 什么是命令模式? 命令模式是一种行为设计模式,它将请求封装为一个对象,从而使您能够使用不同的请求、队列或日志请求,以及支持可撤销操作。 命令模式的核心思想是将请求的发送者与请求的接收者解耦,使得两者之间的…...
30天学Java第八天——设计模式
装饰器模式 Decorator Pattern 装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许通过动态地添加功能来扩展对象的行为,而不需要修改原有的类。 这种模式通常用于增强对象的功能,与继承相比,使用…...
Spring事务系列 三
Spring事务的传播机制 Spring事务系列 一-CSDN博客 Spring事务系列 二-CSDN博客 文章目录 系列文章目录 目录 文章目录 前言 一、Spring事务的传播机制 Propagation.REQUIRED: Propagation.SUPPORTS: Propagation.MANDATORY: Propagation.REQUIRES_NEW: Propagation.NOT_SUPPO…...
文件上传做题记录
1,[SWPUCTF 2021 新生赛]easyupload2.0 直接上传php 再试一下phtml 用蚁剑连发现连不上 那就只要命令执行了 2,[SWPUCTF 2021 新生赛]easyupload1.0 当然,直接上传一个php是不行的 phtml也不行,看下是不是前端验证,…...
机器学习的监督学习与无监督学习
机器学习主要分为监督学习和无监督学习两大类,两者的核心区别在于数据是否带有标签(Label)。以下是它们的详细对比和说明: 1. 监督学习(Supervised Learning) 定义:通过带有标签的训练数据&…...
C++ 入门三:函数与模板
一、内联函数:编译期嵌入的 “高效函数” 1. 什么是内联函数? 核心特性:在编译阶段,内联函数的函数体会直接嵌入到调用它的代码中,避免了普通函数的调用开销(如压栈、跳转、返回)。语法&#…...
解析券商qmt的优缺点
现在已经对于大QMT进行了一步步的深入了解与学习,也已经开始积木式搭建策略,进行交易了,但是,随时不断的深入,发现的问题也越来越多。下面开始逐一解析: 首页 | 迅投知识库 这是详细的说明。 目前券商给大…...
CSE lesson2 chrony服务器
CSE lesson2 chrony服务器 timedatectl命令 NTP(network time protocal)网络时间协议,时钟服务器同步时间的时候会使用到该协议进行时间同步。 #关闭/开启时间同步服务 [rootlocalhost ~]# timedatectl set-ntp 0/1#设置时间(必须关闭时间同步服务才能…...
时光交响曲:杭州的科技与传统交响
故事背景 故事发生在中国浙江杭州,以现代科技与文化传统的交融为背景,展现了人与自然、历史的深刻联系。在晨曦中的茶园、宁静的运河书屋、科技堤坝等地方,每个场景都充满了生机与活力,展示了科技如何赋予传统文化新的生命&#x…...
【大模型智能体】Agent2Agent协议加上MCP协议也许会成为未来Agent智能体系统的标配
之前在文章《基于Claude MCP协议的智能体落地示例》、《MCP(Model Context Protocol) 大模型智能体第一个开源标准协议》我们已经对MCP协议做了介绍,MCP提供了将大模型连接到不同数据源和工具的标准方式,包括内容仓库、商业工具和开发环境。 以上解决的是…...
opencv(C++)处理图像颜色
文章目录 介绍使用策略设计模式比较颜色实现方案计算两个颜色向量之间的距离1. 简单方法:曼哈顿距离计算(Manhattan Distance)2.使用 OpenCV 的 cv::norm 函数3.使用 OpenCV 的 cv::absdiff 函数错误示例 使用 OpenCV 函数实现颜色检测实现方…...
2025年焊接与热切割作业证考试真题分享
焊接与热切割作业属于特种作业操作证考试,理论知识点专业性强、安全规范要求高,如何高效备考成为关键!【100分题库】焊接与热切割作业理论备考题库紧扣最新考试大纲,帮你系统掌握考点,一次通过考试! 1、下…...
AI 代码生成工具如何突破 Java 单元测试效能天花板?
一、传统单元测试的四大痛点 时间黑洞:根据 JetBrains 调研,Java 开发者平均花费 35% 时间编写测试代码覆盖盲区:手工测试覆盖率普遍低于 60%(Jacoco 全球统计数据)维护困境:业务代码变更导致 38% 的测试用…...
【C++游戏引擎开发】第13篇:光照模型与Phong基础实现
一、Phong模型数学原理 1.1 光照叠加公式 L = k a I a + k d I d max ( 0 , n ⋅ l ) + k s I s max ( 0 , r ⋅ v ) α L = k_a I_a + k_d I_d \max(0, \mathbf{n} \cdot \mathbf{l}) + k_s I_s \max(0, \mathbf{r} \cdot \mathbf{v})^\alpha L=kaIa+kdIdmax(0…...
如何在Android系统上单编ko?
文章目录 一、先了解编译驱动需要什么?二、配置makefile1、在Android系统编译LOG上找到编译器信息(一般都会打印出来)2、基于源MK构造 可独立运行的makefile3)进入docker,在此makefile目录下敲make4)最后根…...
虚拟dom工作原理以及渲染过程
浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTML分析器,分析HTML元素,构建一颗DOM树(标记化和树构建)。 第二步,用…...
无人机视觉定位,常用相机,及相机提供的数据信息
常用相机类型 单目相机:仅使用一个摄像头进行图像采集,结构简单、成本低。它可以获取无人机前方或下方的二维图像信息,包括物体的形状、颜色、纹理等。双目相机:由两个摄像头组成,模拟人类双眼视觉原理,通…...
A2L文件解析
目录 1 摘要2 A2L文件介绍2.1 A2L文件作用2.2 A2L文件格式详解2.2.1 A2L文件基本结构2.2.2 关键元素与声明2.2.3 完整A2L文件示例 3 总结 1 摘要 A2L文件(也称为ASAP2文件)是ECU开发的核心接口文件,用于标定、测量和诊断的关键配置文件&…...
Ansible:role企业级实战
文章目录 实现 nginx 角色创建task文件创建handler文件准备模板文件创建变量文件在playbook中调用角色 实现 memcached 角色创建相关目录创建相关task任务准备模板文件查看目录结构在playbook中调用角色 实现多角色的选择 实现 nginx 角色 卸载httpd,创建相关目录 a…...
vue2使用vue-echarts
1.先安装echarts npm i echarts 2.安装vue-echarts 安装的时候注意下对应的版本 "echarts": "5.5.0", "vue-echarts": "6.7.3",这是我安装的版本 注意事项: 如果安装之后报错:"export watchEffect …...
多光谱相机:海洋管道漏油(溢油)监测
每年海上溢油和化工管道漏油造成的污染事故和经济损失频发,在生态方面,漏油会带来导致水质恶化、生态系统破坏、食物链受损。在经济方面,会造成渔业损失、旅游业损失、航运业损失。在健康方面,会造成食品安全问题,直接…...
Kaggle-Digit Recognizer-(多分类+卷积神经网络CNN)
Digit Recognizer 题意: 给你每个图片的dataframe类型的数据,让你预测出每个图片可能是多少。 思考: 数据处理 1.首先把数据从dadaframe转换成numpy,数据类型改为float32,并且并且展开为1维的28281的形状…...
jQuery多库共存
在现代Web开发中,项目往往需要集成多种JavaScript库或框架来满足不同的功能需求。然而,当多个库同时使用时,可能会出现命名冲突、功能覆盖等问题。幸运的是,jQuery提供了一些机制来确保其可以与其他库和谐共存。本文将探讨如何实现…...
MCU的USB接口作为 USB CDC串口输出
前言: 如下内容是和Chatgpt的问答对话。询问了Chatgpt 关于 MCU微控制器内部的USB端口作为串口输出是怎么工作的,是否需要在上位机上安装串口驱动程序等,Chatgpt解答的很好。 正文: STM32 使用USB作为串行设备端口,需…...
VCode 的 .S 汇编文件里面的注释不显示绿色
1. 确认文件语言模式 打开 .S 文件后,查看 VS Code 右下角的状态栏,确认当前文件的识别模式(如 Assembly、Plain Text 等)。如果显示为 Plain Text 或其他非汇编模式: 点击状态栏中的语言模式(如 Plain Te…...
【数学建模】(智能优化算法)萤火虫算法(Firefly Algorithm)详解与实现
萤火虫算法(Firefly Algorithm)详解与实现 文章目录 萤火虫算法(Firefly Algorithm)详解与实现前言1. 算法原理2. 算法流程3. Python实现4. 算法特点4.1 优点4.2 缺点 5. 应用领域6. 算法变种7. 总结与展望参考文献 前言 大家好,今天给大家介绍一种有趣且高效的群体…...
链路追踪组件学习
目录 1. 为啥需要链路追踪2. 常见的链路追踪组件3. 使用过的链路追踪组件3.1. Spring Cloud Sleuth3.2. Zipkin3.3. Apache SkyWalking 4. 集成Spring Cloud Sleuth框架4.1. 流程步骤4.2 sleuth工作流程 5. 集成zipKin5.1 添加 Zipkin 相关依赖5.2 安装zipkin服务5.3 配置 Zipk…...
# 基于OpenCV与Dlib的人脸融合技术实现
从仿射变换到人脸融合:基于OpenCV和Dlib的图像处理实践 在图像处理领域,仿射变换和人脸融合是两个非常有趣且实用的技术。仿射变换可以用于图像的几何变换,而人脸融合则可以创造出令人惊叹的视觉效果。本文将通过两个具体的代码示例…...
多光谱相机:水环境监测(水体富营养化、黑臭水体、藻类水华)
随着全球水体污染问题日益严峻,水体富营养化、黑臭水体和藻类水华等生态危机对人类健康和水生系统构成重大威胁。传统监测手段(如人工采样、单点传感器)因效率低、覆盖不足、实时性差等局限,难以满足复杂水环境的动态监管需求。多…...
记录一次nginx访问前端首页,一直显示nginx首页问题(实际是nginx访问页面权限问题)
同一台服务器,nginx配置是server { listen 8081; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location /New_mh_other { alias /home/hqu/data/new_mh_other; try…...
windows下命名管道双端通信
实现功能 1、命名管道双端通信(异步) 2、客户端断线重连 PS:多线程版本 PipeWrapper.h #include <windows.h> #include <string> #include <vector> #include "Utils/ThreadObject.h" #include "Utils/T…...
Linux自行实现的一个Shell(15)
文章目录 前言一、头文件和全局变量头文件全局变量 二、辅助函数获取用户名获取主机名获取当前工作目录获取最后一级目录名生成命令行提示符打印命令行提示符 三、命令处理获取用户输入解析命令行执行外部命令 四、内建命令添加环境变量检查和执行内建命令 五、初始化初始化环境…...
powerDesign 逆向 mysql 生成 物理模型,并用VBS脚本整理comment
学习自:https://www.cnblogs.com/xmyjcs/p/8536233.html 文章目录 Reverse Engineer格式化模型执行 VBS 脚本 Reverse Engineer 下面 DBMS 可以通过 ODBC(Open Database Connectivity,开放数据库连接)连接, 需要自己先…...
跨境全域中台:前端独立站群+后端共享云仓的协同作战体系
在全球化浪潮与互联网技术飞速发展的当下,跨境电商已然成为国际贸易领域中最为活跃的力量。据相关数据显示,过去几年跨境电商的年增长率持续保持高位,越来越多的企业投身于这片充满机遇与挑战的蓝海市场。在竞争日益激烈的跨境电商赛道上&…...
国产芯片解析:乐得瑞LDR6500C 超小封装全能芯片,赋能智能设备未来
LDR6500C是乐得瑞科技针对USB-C标准中的Bridge设备而开发的双USB-C DRP接口PD通信芯片,具备切换Data Role功能,支持最高USB PD 100W 充电,并且针对各大品牌设备的 USB-C 兼容性进行了特别优化,非常适合于 USB Type-C 设备快充转接…...
代码随想录-06-二叉树-05.10 二叉树的最小深度
二叉树的最小深度 #模板题 题目描述 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明叶子节点是指没有子节点的节点 具体思路(暴力) 层序遍历;找到cur.left null && cur.ri…...
系统与网络安全------网络通信原理(6)
资料整理于网络资料、书本资料、AI,仅供个人学习参考。 应用层解析 DNS Domain Name System,域名系统 用来完成域名与IP地址之间的映射,便于用户对网站的记忆和访问 端口号为TCP或UDP的53 DNS工作原理 FTP File Transfer Protocol 文件…...
【Vue #2】脚手架 指令
一、脚手架 脚手架:一个保证各项工作顺利开展的平台,方便我们 拿来就用,零配置 1. Vue 代码开发方式 相比直接 script 引入 vue 源码,有没有更好的方式编写vue代码呢? ① 传统开发模式: 基于html文件开发Vue&…...
UE5 后坐力枪口上抬和恢复
文章目录 计算后坐力并让视角上抬后坐力回落 计算后坐力并让视角上抬 在玩家蓝图里,声明一个方法OnShootOnce,在武器每次射击时调用 1检测新的后坐力是否超过了最大后坐力,并选择一个小的 2 如何将角色模型设置为相机的子物体 3 最后记录一下当前的…...
Mysql B+树高度如何计算?
MySQL 的 InnoDB 存储引擎使用 B+树 作为索引结构,其高度增加会直接影响查询性能(每次高度增加意味着多一次磁盘 I/O)。以下是 B+树高度增加的 关键场景 和 优化建议: 1. B+树高度增加的触发条件 (1) 数据量持续增长 根本原因:B+树的层级由数据量(记录数)和每个节点的容…...
UE5 使用贴花创建弹孔
文章目录 使用射线检测击中点在击中点处创建贴花 使用射线检测击中点 和untiy一样,发射一条射线,在命中点处创建弹孔 在武器里定义射击检测方法 以下是对上边使用的方法的展开 GetShootStartPosition:获取射击起点 computeShootEndPosition:…...
程序持续内存泄漏问题定位参考
0 概括 本文用于记录 x86-Linux 应用程序发生持续性内存泄漏问题时的定位方法。主要介绍valgrind工具的应用。 1 原理 对于内存泄漏问题的定位,一种朴素的想法就是对内存申请点进行监控。对于一个内存申请调用点(例如c/c中的malloc函数)&a…...
Lumion 与 Enscape 怎么选?附川翔云电脑适配指南
建筑可视化领域,Lumion 和 Enscape 是两款主流实时渲染器,核心差异体现在操作逻辑、渲染特性及适用场景。结合川翔云电脑平台的硬件支持,可进一步优化使用体验。 一、核心差异:效率、操作与场景适配 1. 操作门槛与实时性 Lumio…...
WebShell详解:原理、分类、攻击与防御
目录 一、WebShell的定义与核心概念 二、WebShell的分类 三、WebShell的攻击原理与常见手法 1. 攻击原理 2. 常见攻击路径 四、WebShell的危害 五、防御与检测策略 六、总结 一、WebShell的定义与核心概念 WebShell是一种以ASP、PHP、JSP等网页脚本形式存在的恶…...
Ubuntu 24.04 中文输入法安装
搜狗输入法,在Ubuntu 24.04上使用失败,安装教程如下 https://shurufa.sogou.com/linux/guide 出现问题的情况,是这个帖子里描述的: https://forum.ubuntu.org.cn/viewtopic.php?t493893 后面通过google拼音输入法解决了&#x…...
数码视讯TR100系列/TR100-G1/TR100-G4/数码视讯F7-国科GK6323V100C芯片-刷机固件包
数码视讯TR100系列/数码视讯TR100-G1/数码视讯TR100-G4/数码视讯F7-国科GK6323V100C芯片-刷机固件包 刷机教程: 里面共有两种方法,一是TTL线刷烧录方法;二是卡刷固件包; 下面以数码视讯TR100-…...
Cloudflare教程:免费优化CDN加速配置,提升网站访问速度 | 域名访问缓存压缩视频图片媒体文件优化配置
1、启用 Tiered Cache 缓存开关:通过选择缓存拓扑,可以控制源服务器与 Cloudflare 数据中心的连接方式,以确保缓存命中率更高、源服务器连接数更少,并且 Internet 延迟更短。 2、增加浏览器缓存时间TTL:在此期间&#…...
24体育NBA足球直播M24模板自适应板源码
源码名称:体育直播赛事扁平自适应M24直播模板源码 开发环境:帝国cms7.5 空间支持:phpmysql 带软件采集,可以挂着自动采集发布,无需人工操作! 演示地址:https://www.52muban.com/shop/184022.h…...
dify+wan2.1搭建文生视频生成工具流
本文介绍在dify中使用阿里开源的Wan2.1 1.3B模型搭建文生视频工作流的方法。 使用的工具如下: 1、dify(官方:https://docs.dify.ai/zh-hans) 2、comfyui 一、comfyui安装 为了简单起见,本文介绍使用autodl完成comfyui的部署。在autodl创建实例,使用的镜像如下图: 大…...
C# js 判断table中tr否存在相同的值
html 中如: 实现:table数据表格中,点击删除按钮时,验证相同子订单号条数是否大于1,大于允许删除。保证数据表格中只有唯一的一条子订单号数据。 <table style"width: 100%; background-color: #fff;" ce…...