当前位置: 首页 > news >正文

C++命令模式 指挥家:掌控命令模式之美

C++指挥家:掌控命令模式之美 (C++ Conductor: Master the Beauty of Command Pattern

  • 一、引言 (Introduction)
    • 1.1 命令模式概述 (Overview of Command Pattern)
    • 1.2 命令模式的应用场景 (Application Scenarios of Command Pattern)
  • 二、命令模式的基本概念 (Basic Concepts of Command Pattern)
    • 2.1 接收者(Receiver)
    • 2.2 命令(Command)
    • 2.3 调用者(Invoker)
    • 2.4 具体命令(Concrete Command)
    • 2.5 命令模式UML图
  • 三、C++实现命令模式 (Implementing Command Pattern in C++)
    • 3.1 设计接收者类 (Designing the Receiver Class)
    • 3.2 设计命令接口 (Designing the Command Interface)
    • 3.3 实现具体命令类 (Implementing the Concrete Command Classes)
  • 四、命令模式的优缺点 (Pros and Cons of Command Pattern)
    • 4.1 命令模式的优点 (Advantages of Command Pattern)
    • 4.2 命令模式的缺点 (Disadvantages of Command Pattern)
  • 五、命令模式的应用实例 (Application Examples of Command Pattern)
    • 5.1 图形编辑器 (Graphic Editor)
    • 5.2 播放器控制 (Player Control)
  • 六、结语

一、引言 (Introduction)

1.1 命令模式概述 (Overview of Command Pattern)

命令模式(Command Pattern)是一种行为型设计模式,主要用于将请求发送者和请求接收者解耦。该模式涉及四个角色:接收者(Receiver)、命令(Command)、调用者(Invoker)和具体命令(Concrete Command)。命令模式的核心思想是将请求封装成对象,从而实现对操作的高度灵活性。

Command Pattern is a behavioral design pattern that primarily decouples the request sender and the request receiver. It involves four roles: Receiver, Command, Invoker, and Concrete Command. The core idea of the command pattern is to encapsulate requests into objects, thereby achieving high flexibility for operations.

1.2 命令模式的应用场景 (Application Scenarios of Command Pattern)

命令模式适用于以下几种场景:

  1. 当需要将请求发送者和请求接收者解耦时,可以使用命令模式。这使得调用者和接收者之间的联系变得更加松散,增强了系统的灵活性。
  2. 当需要实现对请求的撤销、重做或者存储请求操作历史记录等功能时,命令模式可以为你提供帮助。
  3. 当系统需要支持一组可配置的操作时,命令模式可以实现动态地组合操作和修改操作顺序。
  4. 当系统需要实现异步操作或者需要将操作放入队列中进行处理时,命令模式也很适用。

Command pattern is suitable for the following scenarios:

  1. When you need to decouple the request sender and request receiver, you can use the command pattern. This makes the connection between the caller and the receiver more relaxed, enhancing the flexibility of the system.
  2. When you need to implement undo, redo, or store request operation history, the command pattern can help you.
  3. When the system needs to support a set of configurable operations, the command pattern can dynamically combine and modify operation orders.
  4. When the system needs to implement asynchronous operations or needs to put operations into a queue for processing, the command pattern is also very suitable.

二、命令模式的基本概念 (Basic Concepts of Command Pattern)

2.1 接收者(Receiver)

接收者(Receiver)是命令模式中负责执行具体操作的对象。它包含了所有操作的具体实现方法。通常情况下,接收者与命令本身是分离的,它们之间不直接交互。

Receiver is the object responsible for executing specific operations in the Command Pattern. It contains all the specific implementation methods of the operations. Generally, the receiver is separate from the command itself, and they do not interact directly.

2.2 命令(Command)

命令(Command)是一个抽象类或接口,它定义了一个名为execute()的方法,该方法接受一个接收者(Receiver)实例作为参数。命令对象用于封装执行某个操作的请求,将请求与实际的操作解耦。

Command is an abstract class or interface that defines a method called execute(), which takes a Receiver instance as a parameter. The command object is used to encapsulate a request to perform an operation, decoupling the request from the actual operation.

2.3 调用者(Invoker)

调用者(Invoker)负责发起请求和执行命令。它包含了一个或多个命令对象,并且在需要时触发命令对象的execute()方法。调用者不需要关心命令的具体实现,只需要知道如何发起请求。

Invoker is responsible for initiating requests and executing commands. It contains one or more command objects and triggers the execute() method of the command object when needed. The invoker does not need to care about the specific implementation of the command, it only needs to know how to initiate a request.

2.4 具体命令(Concrete Command)

具体命令(Concrete Command)是命令接口的具体实现。每一个具体命令都包含了一个接收者(Receiver)实例,该实例负责执行与该命令相关的操作。当调用者触发execute()方法时,具体命令将调用接收者的相应方法以完成实际操作。

Concrete Command is the specific implementation of the Command interface. Each concrete command contains a Receiver instance responsible for performing the operation associated with the command. When the invoker triggers the execute() method, the concrete command will call the corresponding method of the receiver to complete the actual operation.

2.5 命令模式UML图

命令模式的UML图包含以下几个关键部分:

  1. Command(抽象命令):一个接口或抽象类,定义了execute()方法。
  2. ConcreteCommand(具体命令):实现Command接口的具体类,实现了execute()方法,并持有Receiver的引用。
  3. Receiver(接收者):执行具体操作的类,包含具体操作的实现方法。
  4. Invoker(调用者):持有Command对象的类,负责发起请求和执行命令。

以下是命令模式的UML图:

+-------------------+      +-------------------+      +--------------------+
|    Invoker        |      |     Command       |      |    Receiver        |
+-------------------+      +-------------------+      +--------------------+
| +setCommand(cmd)  |<-----| +execute() : void |----->| +action() : void   |
| +executeCommand() |      +-------------------+      +--------------------+
+-------------------+              ^                            ^|                            |+------------------+          +---------------+| ConcreteCommand  |          | SpecificReceiver |+------------------+          +---------------+| +execute() : void |          | +action() : void |+------------------+          +---------------+

在此UML图中,Invoker类通过setCommand()方法设置ConcreteCommand对象,并通过executeCommand()方法触发ConcreteCommand对象的execute()方法。ConcreteCommand类实现了Command接口,并在其execute()方法中调用Receiver类的具体操作。具体的Receiver类包含了操作的实现方法。

三、C++实现命令模式 (Implementing Command Pattern in C++)

3.1 设计接收者类 (Designing the Receiver Class)

首先,我们需要设计一个接收者类,这个类包含了具体操作的实现方法。在本例中,我们将创建一个名为Light的类,它有一个turnOn()方法来表示开灯操作,一个turnOff()方法表示关灯操作。

#include <iostream>class Light {
public:void turnOn() {std::cout << "Light is on." << std::endl;}void turnOff() {std::cout << "Light is off." << std::endl;}
};

在这个例子中,Light类代表接收者(Receiver),负责执行与开灯和关灯相关的操作。

3.2 设计命令接口 (Designing the Command Interface)

接下来,我们需要定义一个命令接口。在C++中,我们可以使用抽象类来表示接口。我们将创建一个名为Command的抽象类,其中包含一个纯虚函数execute()

class Command {
public:virtual void execute() = 0;
};

3.3 实现具体命令类 (Implementing the Concrete Command Classes)

现在,我们需要为每个具体操作创建具体命令类。在本例中,我们需要创建两个具体命令类:TurnOnLightCommandTurnOffLightCommand。这两个类都继承自Command抽象类,并实现execute()方法。每个具体命令类都包含一个Light对象的引用,用于执行实际的操作。

class TurnOnLightCommand : public Command {
private:Light &light;public:TurnOnLightCommand(Light &light) : light(light) {}void execute() override {light.turnOn();}
};class TurnOffLightCommand : public Command {
private:Light &light;public:TurnOffLightCommand(Light &light) : light(light) {}void execute() override {light.turnOff();}
};

在这个例子中,我们通过构造函数将Light对象的引用传递给具体命令类,使得具体命令类能够执行实际操作。TurnOnLightCommand类实现了execute()方法,调用light.turnOn();而TurnOffLightCommand类实现了execute()方法,调用light.turnOff()

四、命令模式的优缺点 (Pros and Cons of Command Pattern)

4.1 命令模式的优点 (Advantages of Command Pattern)

  1. 解耦请求发送者与请求接收者:命令模式将请求发送者(Invoker)与请求接收者(Receiver)解耦,使它们之间的联系变得更加松散,有助于系统的灵活性和可扩展性。
  2. 易于扩展新命令:使用命令模式时,如果需要添加新的操作,只需要实现一个新的具体命令类即可,无需修改已有的代码。
  3. 支持撤销、重做等操作:命令模式可以轻松地实现撤销、重做等功能。通过存储已执行的命令对象,并实现相应的撤销和重做方法,可以实现这些功能。
  4. 支持将命令放入队列和异步执行:命令模式可以将多个命令放入队列中进行处理。此外,它还可以支持异步操作,将操作放入后台线程中执行。

4.2 命令模式的缺点 (Disadvantages of Command Pattern)

  1. 增加了系统的复杂性:命令模式引入了许多新的类,如抽象命令类、具体命令类等。这使得系统的复杂性增加,增加了学习和理解的难度。
  2. 可能导致类数量过多:由于每个操作都需要一个具体命令类,所以当有大量操作时,可能导致类数量急剧增加,使系统变得庞大和难以维护。
  3. 增加了间接性:命令模式将请求发送者与接收者之间增加了一个抽象层次。这虽然带来了一定程度的解耦,但也增加了系统的间接性,可能导致调试和定位问题更加困难。

尽管命令模式有一些缺点,但在合适的场景下,它仍然是一种非常有用的设计模式。在需要解耦发送者和接收者、易于扩展新命令或支持撤销、重做等功能的系统中,命令模式是一个很好的选择。

五、命令模式的应用实例 (Application Examples of Command Pattern)

5.1 图形编辑器 (Graphic Editor)

首先,我们创建一个简化版的图形编辑器,实现如下功能:添加圆形、删除圆形、打印当前图形。

#include <iostream>
#include <vector>
#include <memory> // C++11特性: shared_ptr
#include <algorithm> // C++14特性: std::find_if, std::remove_if
#include <any> // C++17特性: std::anyclass Circle {
public:Circle(int id) : id(id) {}void draw() const {std::cout << "Draw circle with ID: " << id << std::endl;}int getID() const {return id;}private:int id;
};class GraphicEditor {
public:void addCircle(std::shared_ptr<Circle> circle) {circles.push_back(circle);}void removeCircle(int id) {circles.erase(std::remove_if(circles.begin(), circles.end(),[id](const auto& circle) { return circle->getID() == id; }), // C++14特性: auto, lambda expressioncircles.end());}void printCircles() const {std::cout << "Current circles:" << std::endl;for (const auto& circle : circles) { // C++11特性: auto, range-based for loopcircle->draw();}}private:std::vector<std::shared_ptr<Circle>> circles;
};

现在,我们将使用命令模式重构图形编辑器。

// Command Interface
class Command {
public:virtual ~Command() = default; // C++11特性: 默认函数=defaultvirtual void execute() = 0;
};// Concrete Command: AddCircleCommand
class AddCircleCommand : public Command {
public:AddCircleCommand(GraphicEditor& editor, int id) : editor(editor), circle(std::make_shared<Circle>(id)) {} // C++14特性: std::make_sharedvoid execute() override {editor.addCircle(circle);}private:GraphicEditor& editor;std::shared_ptr<Circle> circle;
};// Concrete Command: RemoveCircleCommand
class RemoveCircleCommand : public Command {
public:RemoveCircleCommand(GraphicEditor& editor, int id) : editor(editor), id(id) {}void execute() override {editor.removeCircle(id);}private:GraphicEditor& editor;int id;
};// Invoker: CommandHandler
class CommandHandler {
public:void setCommand(std::shared_ptr<Command> command) {this->command = command;}void executeCommand() {if (command) {command->execute();}}private:std::shared_ptr<Command> command;
};int main() {GraphicEditor editor;CommandHandler handler;auto addCircleCommand = std::make_shared<AddCircleCommand>(editor, 1);auto removeCircleCommand = std::make_shared<RemoveCircleCommand>(editor, 1);handler.setCommand(addCircleCircleCommand);handler.executeCommand(); // 添加圆形editor.printCircles(); // 输出: Draw circle with ID: 1handler.setCommand(addCircleCommand);handler.executeCommand(); // 再次添加圆形editor.printCircles(); // 输出: Draw circle with ID: 1, Draw circle with ID: 1handler.setCommand(removeCircleCommand);handler.executeCommand(); // 删除圆形editor.printCircles(); // 输出: Draw circle with ID: 1std::any userData; // C++17特性: std::anyuserData = 42;std::cout << "UserData: " << std::any_cast<int>(userData) << std::endl; // 输出: UserData: 42return 0;}

在上面的代码中,我们使用了命令模式重构了简化版的图形编辑器,并展示了如何添加和删除圆形。同时,我们使用了C++11,C++14和C++17的特性,如shared_ptrautolambda expressionmake_sharedany等,并提供了详细注释。

5.2 播放器控制 (Player Control)

首先,我们创建一个简化版的播放器:

#include <iostream>
#include <memory> // C++11特性: shared_ptr
#include <any> // C++17特性: std::any
#include <optional> // C++17特性: std::optionalclass Player {
public:void play() {std::cout << "Playing..." << std::endl;}void pause() {std::cout << "Paused." << std::endl;}void stop() {std::cout << "Stopped." << std::endl;}
};

现在,我们将使用命令模式重构播放器控制:

// Command Interface
class Command {
public:virtual ~Command() = default; // C++11特性: 默认函数=defaultvirtual void execute() = 0;
};// Concrete Command: PlayCommand
class PlayCommand : public Command {
public:explicit PlayCommand(Player& player) : player(player) {} // C++11特性: explicit关键字void execute() override {player.play();}private:Player& player;
};// Concrete Command: PauseCommand
class PauseCommand : public Command {
public:explicit PauseCommand(Player& player) : player(player) {}void execute() override {player.pause();}private:Player& player;
};// Concrete Command: StopCommand
class StopCommand : public Command {
public:explicit StopCommand(Player& player) : player(player) {}void execute() override {player.stop();}private:Player& player;
};// Invoker: RemoteController
class RemoteController {
public:void setCommand(std::shared_ptr<Command> command) {this->command = command;}void pressButton() {if (command) {command->execute();}}private:std::shared_ptr<Command> command;
};int main() {Player player;RemoteController remote;auto playCommand = std::make_shared<PlayCommand>(player);auto pauseCommand = std::make_shared<PauseCommand>(player);auto stopCommand = std::make_shared<StopCommand>(player);remote.setCommand(playCommand);remote.pressButton(); // 输出: Playing...remote.setCommand(pauseCommand);remote.pressButton(); // 输出: Paused.remote.setCommand(stopCommand);remote.pressButton(); // 输出: Stopped.// C++17特性: std::optionalstd::optional<int> maybeValue;if (!maybeValue.has_value()) { // 当前没有值maybeValue = 42;}if (maybeValue.has_value()) { // 现在有值了std::cout << "Optional value: " << maybeValue.value() << std::endl; // 输出: Optional value: 42}return 0;
}

六、结语

在本篇博客中,我们详细介绍了C++中命令模式的概念、原理、优缺点以及在图形编辑器和播放器控制中的应用。通过学习命令模式,我们不仅可以提高自己的编程技巧,还可以更好地理解面向对象设计原则,提升编程思维。

从心理学角度来看,学习和理解设计模式对个人和团队都具有积极意义。首先,设计模式提供了一种解决问题的共同语言,有助于团队成员之间的有效沟通,降低沟通成本。其次,设计模式可以提高程序员的自信心,因为它们代表了行业内公认的最佳实践。使用设计模式可以使程序员确信自己的解决方案是高效、稳定的,从而提高工作满意度。

此外,学习设计模式有助于培养程序员的创新思维。了解现有的设计模式可以帮助我们站在巨人的肩膀上,以更高的起点开始思考问题。在学习和理解现有设计模式的基础上,我们可以更好地发现潜在的设计问题,甚至可能提出新的设计模式。

总之,本篇博客通过深入浅出的介绍和示例,让读者更好地理解和掌握命令模式。从心理学角度看,学习命令模式不仅有助于提高编程技能,还可以促进团队协作,激发创新思维。希望本篇博客能给您带来启发和收获,祝您学习愉快!

相关文章:

C++命令模式 指挥家:掌控命令模式之美

C指挥家&#xff1a;掌控命令模式之美 (C Conductor: Master the Beauty of Command Pattern一、引言 (Introduction)1.1 命令模式概述 (Overview of Command Pattern)1.2 命令模式的应用场景 (Application Scenarios of Command Pattern)二、命令模式的基本概念 (Basic Concep…...

学会 制作极简搜索浏览器 —— 并将 ChatGPT 接入浏览器

前期回顾 Vue3 Ts Vite pnpm 项目中集成 —— eslint 、prettier、stylelint、husky、commitizen_0.活在风浪里的博客-CSDN博客搭建VIte Ts Vue3项目并集成eslint 、prettier、stylelint、huskyhttps://blog.csdn.net/m0_57904695/article/details/129950163?spm1001.2…...

NumPy 秘籍中文第二版:六、特殊数组和通用函数

原文&#xff1a;NumPy Cookbook - Second Edition 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 在本章中&#xff0c;我们将介绍以下秘籍&#xff1a; 创建通用函数查找勾股三元组用chararray执行字符串操作创建一个遮罩数组忽略负值和极值使用recarray函数创建一…...

各种交叉编译工具链的区别

目录 1 命名规则 2 实例 2.1 arm-none-eabi-gcc 2.2 arm-none-linux-gnueabi-gcc 2.3 arm-eabi-gcc 2.4 armcc 2.5 arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc 3 gnueabi和gnueabihf的区别(硬浮点、软浮点) 4 Linaro公司出品的交叉编译工具链 5 ARM公司出…...

密度聚类算法(DBSCAN)实验案例

密度聚类算法&#xff08;DBSCAN&#xff09;实验案例 描述 DBSCAN是一种强大的基于密度的聚类算法&#xff0c;从直观效果上看&#xff0c;DBSCAN算法可以找到样本点的全部密集区域&#xff0c;并把这些密集区域当做一个一个的聚类簇。DBSCAN的一个巨大优势是可以对任意形状…...

第07章_面向对象编程(进阶)

第07章_面向对象编程(进阶) 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题与脉络 1. 关键字&#xff1a;this 1.1 this是什么&#xff1f; 在Java中&#xff0c;this关键字不算难理解…...

异常的讲解(2)

目录 throws异常处理 基本介绍 throws异常处理注意事项和使用细节 自定义异常 基本概念 自定义异常的步骤 throw 和throws的区别 本章作业 第一题 第二题 第三题 第四题 throws异常处理 基本介绍 1)如果一个方法(中的语句执行时)可能生成某种异常&#xff0c;但是…...

jvm内存结构

1. 栈 程序计数器 2. 虚拟机栈 3. 本地方法栈 4. 堆 5. 方法区 1.2栈内存溢出 栈帧过多导致栈内存溢出 /*** 演示栈内存溢出 java.lang.StackOverflowError* -Xss256k*/ public class Demo1_2 {private static int count;public static void main(String[] args) {try {meth…...

要刹车?生成式AI迎新规、行业连发ChatGPT“警报”、多国考虑严监管

4月13日消息&#xff0c;据中国移动通信联合会元宇宙产业工作委员会网站&#xff0c;中国移动通信联合会元宇宙产业工作委员会、中国通信工业协会区块链专业委员会等&#xff0c;共同发布“关于元宇宙生成式人工智能&#xff08;类 ChatGPT&#xff09;应用的行业提示”。提示内…...

轻松掌握Qt FTP 机制:实现高效文件传输

轻松掌握Qt FTP&#xff1a;实现高效文件传输一、简介&#xff08;Introduction&#xff09;1.1 文件传输协议&#xff08;FTP&#xff09;Qt及其网络模块&#xff08;Qt and its Network Module&#xff09;QNetwork:二、QNetworkAccessManager上传实例&#xff08;Qt FTP Upl…...

用AI帮我写一篇关于FPGA的文章,并推荐最热门的FPGA开源项目

FPGA定义 FPGA&#xff08;Field Programmable Gate Array&#xff09;是一种可编程逻辑器件&#xff0c;可以在硬件电路中实现各种不同的逻辑功能。与ASIC&#xff08;Application Specific Integrated Circuit&#xff0c;特定应用集成电路&#xff09;相比&#xff0c;FPGA…...

从兴趣或问题出发

当我们还沉寂在移动互联网给生活带来众多便利中&#xff0c;以 ChartGPT 为代表的 AI 时代已彻底到来。科技的发展&#xff0c;时刻在改变着我们的生活&#xff0c;我们需要不断地学习新知识和掌握新技能才能享受变化带来的便利&#xff0c;以及自身不被社会淘汰。 因此&#…...

C++ | 探究拷贝对象时的一些编译器优化

&#x1f451;作者主页&#xff1a;烽起黎明 &#x1f3e0;学习社区&#xff1a;烈火神盾 &#x1f517;专栏链接&#xff1a;C 文章目录前言一、传值传参二、传引用传参三、传值返回拷贝构造和赋值重载的辨析四、传引用返回【❌】五、传匿名对象返回六、总计与提炼前言 在传参…...

linux工具gcc/g++/gdb/git的使用

目录 gcc/g 基本概念 指令集 函数库 &#xff08;重要&#xff09; gdb使用 基本概念 指令集 项目自动化构建工具make/makefile 进度条小程序 ​编辑 git三板斧 创建仓库 git add git commit git push git status git log gcc/g 基本概念 gcc/g称为编译器…...

Direct3D 12——纹理——纹理

纹理不同于缓冲区资源&#xff0c;因为缓冲区资源仅存储数据数组&#xff0c;而纹理却可以具有多个mipmap层级(后 文有介绍)&#xff0c;GPU会基于这个层级进行相应的特殊操作&#xff0c;例如运用过滤器以及多重采样。支持这些特殊 的操作纹理资源都被限定为一些特定的数据格式…...

产品经理必读 | 俞军产品经理十二条军规

最近在学习《俞军产品方法论》&#xff0c;觉得俞军总结的十二条产品经理原则非常受用&#xff0c;分享给大家。 01. 产品经理首先是产品的深度用户 自己设计的产品都没使用过的产品经理&#xff0c;如何明白用户使用的问题&#xff0c;如何解决问题&#xff0c;所以产品经理肯…...

【机器视觉1】光源介绍与选择

文章目录一、常见照明光源类型二、照明光源对比三、照明技术3.1 亮视野与暗视野3.2 低角度照明3.3 前向光直射照明3.4 前向光漫射照明3.5 背光照明-测量系统的最佳选择3.6 颜色与补色示例3.7 偏光技术应用四、镜头4.1 镜头的几个概念4.2 影响图像质量的关键因素4.3 成像尺寸4.4…...

【三十天精通Vue 3】第十一天 Vue 3 过渡和动画详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录引言一、Vue 3 过度和动画概述1.1过度和动画的简介二、Vue 3 过度2…...

基于多种流量检测引擎识别pcap数据包中的威胁

在很多的场景下&#xff0c;会需要根据数据包判断数据包中存在的威胁。针对已有的数据包&#xff0c;如何判断数据包是何种攻击呢&#xff1f; 方法一可以根据经验&#xff0c;对于常见的WEB类型的攻击&#xff0c;比如SQL注入&#xff0c;命令执行等攻击&#xff0c;是比较容…...

第02章_变量与运算符

第02章_变量与运算符 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题与脉络 1. 关键字&#xff08;keyword&#xff09; 定义&#xff1a;被Java语言赋予了特殊含义&#xff0c;用做专门…...

SAP ABAP实战:用CO_XT_COMPONENT_CHANGE函数批量修改生产订单组件(附完整代码与锁表避坑指南)

SAP ABAP实战&#xff1a;生产订单组件批量修改的工程化实践 在制造业SAP系统中&#xff0c;生产订单组件的调整是日常运维中的高频操作。当工艺变更、物料替代或紧急缺料时&#xff0c;传统CO02事务码的单条修改方式往往效率低下且容易出错。我曾参与过一个汽车零部件项目&…...

学校/公司服务器没权限升级CUDA?保姆级教程:用conda离线包搞定PyTorch与CUDA版本匹配

无权限环境下的CUDA生存指南&#xff1a;用conda离线包精准匹配PyTorch与GPU驱动 当你面对公司服务器或学校机房中锁死的CUDA 10.2环境&#xff0c;而最新PyTorch版本早已不再支持这个"古董级"驱动时&#xff0c;那种无力感就像被困在数字牢笼里。但别急着放弃——通…...

SKY-lv/doc-generator:为混合语言项目打造轻量级半自动文档生成工具

1. 项目概述&#xff1a;一个文档生成器的诞生与价值最近在整理一个老项目的技术债&#xff0c;发现最头疼的不是代码重构&#xff0c;而是那堆七零八落、版本对不上号的文档。API接口变了&#xff0c;但README里还是老样子&#xff1b;配置文件加了新选项&#xff0c;可文档里…...

从API密钥管理混乱到使用Taotoken统一门户的体验转变

从API密钥管理混乱到使用Taotoken统一门户的体验转变 1. 多厂商密钥管理的痛点 作为个人开发者&#xff0c;我曾同时使用多个不同厂商的大模型API。每个厂商都有独立的控制台、API密钥体系和计费方式。这意味着我需要维护多套密钥&#xff0c;分别登录不同平台查看用量&#…...

MCP服务器自动化部署:为AI应用构建可扩展工具链的Python解决方案

1. 项目概述&#xff1a;一个为AI应用注入“工具箱”的安装服务如果你正在开发基于大语言模型&#xff08;LLM&#xff09;的AI应用&#xff0c;比如一个能帮你分析数据的智能助手&#xff0c;或者一个能自动处理工作流的聊天机器人&#xff0c;你肯定遇到过这样的困境&#xf…...

Homarr:基于React与Docker的自托管服务统一仪表盘部署指南

1. 项目概述与定位如果你和我一样&#xff0c;家里或者公司里跑着一堆自托管服务&#xff0c;从媒体库的Plex、Jellyfin&#xff0c;到自动化下载的Sonarr、Radarr&#xff0c;再到网络管理的Pi-hole&#xff0c;那么你肯定也面临过同一个烦恼&#xff1a;管理入口太分散了。每…...

基于Gemini API的开源UI项目gemiui:从原理到部署的完整实践指南

1. 项目概述&#xff1a;一个为Gemini API量身定制的UI界面如果你最近在折腾AI应用开发&#xff0c;或者单纯想给自己搭建一个更顺手、更可控的AI对话前端&#xff0c;那么你很可能已经听说过或者正在寻找一个合适的开源UI项目。今天要聊的MarkShawn2020/gemiui&#xff0c;就是…...

OneDrive同步总‘挂起’?可能是mklink用错了!详解符号链接的两种用法与避坑指南

OneDrive同步异常&#xff1f;揭秘mklink符号链接的正确打开方式 最近在技术社区看到不少关于OneDrive同步问题的讨论&#xff0c;尤其是使用mklink创建符号链接后出现的"同步挂起"状态。作为一个长期使用OneDrive同步工作文档的用户&#xff0c;我也曾在这个问题上栽…...

农田边缘计算+云端协同:Python实现毫秒级多源时序数据融合(含TensorFlow Lite部署实录)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;农田边缘计算云端协同的农业物联网数据融合概述 在智慧农业演进过程中&#xff0c;农田边缘计算与云端协同正成为解决实时性、带宽约束与全局决策矛盾的关键范式。边缘设备&#xff08;如土壤传感器、无…...

保姆级教程:用Playwright + pytest + Allure 给你的Web自动化测试做个“体检报告”

从零打造企业级Web自动化测试报告&#xff1a;Playwright pytest Allure深度实践指南 当你的自动化测试脚本运行时&#xff0c;是否遇到过这样的困境&#xff1a;测试失败时开发人员无法快速定位问题&#xff0c;管理层对测试结果的可视化程度不满意&#xff0c;团队协作效率…...