当前位置: 首页 > 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;用做专门…...

仅三行就能学会数据分析——Sweetviz详解

文章目录前言一、准备二、sweetviz 基本用法1.引入库2.读入数据3.调整报告布局总结前言 Sweetviz是一个开源Python库&#xff0c;它只需三行代码就可以生成漂亮的高精度可视化效果来启动EDA(探索性数据分析)。输出一个HTML。 如上图所示&#xff0c;它不仅能根据性别、年龄等…...

springboot——集成elasticsearch进行搜索并高亮关键词

目录 1.elasticsearch概述 3.springboot集成elasticsearch 4.实现搜索并高亮关键词 1.elasticsearch概述 &#xff08;1&#xff09;是什么&#xff1a; Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎。 Lucene 可以被认为是迄今为止最先进、性能最好的…...

MATLAB绘制局部放大图

MATLAB绘制局部放大图 1 工具准备 MATLAB官网-ZoomPlot(Kepeng Qiu. Matlab Central, 2022) 初始数据图绘制完成后&#xff0c;调用以下代码&#xff1a; %% 添加局部放大 zp BaseZoom(); zp.plot;1.1 具体绘制步骤 具体绘制步骤如下&#xff1a; 通过鼠标左键框选作图区…...

第十三天缓存一致性篇

目录 一、缓存的应用场景 二、缓存数据一致性如何保证&#xff1f; 三、缓存的最终一致性解决方案&#xff1a; 一、缓存的应用场景 1、缓存中的数据不应该是实时性一致性要求超高的&#xff0c; 通过缓存加上过期时间保证每天拿到的数据都是最新的即可。 2、如果实时性要求…...

VSCode使用Remote SSH远程连接Linux服务器【远程开发】

文章目录前言视频教程1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar4.2 创建隧道映射4.3 测试公网远程连接5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程转发自CSDN远…...

人工智能专题-知识表示

文章目录人工智能专题-知识表示大纲2.1 知识表示的概念2.1.1 知识表示观点2.1.2 知识表示的要求2.2 一阶谓词逻辑表示法2.2.1 一阶谓词概念2.2.2 谓词逻辑表示方法2.3 产生式表示法2.4 语义网络表示法2.5 框架表示法人工智能专题-知识表示 大纲 大纲&#xff1a;掌握知识表示方…...

各种过滤器使用场景

授权过滤器的使用场景有以下几种&#xff1a; 判断用户是否登录或具有访问权限&#xff0c;如使用Authorize特性来限制只有通过身份验证的用户才能访问某些控制器或操作方法。 实现自定义的授权逻辑&#xff0c;如根据用户的角色、权限、IP地址等来决定是否允许访问。 实现一…...

第04章_IDEA的安装与使用(下)

第04章_IDEA的安装与使用&#xff08;下&#xff09; 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 8. 快捷键的使用 8.1 常用快捷键 见《尚硅谷_宋红康_IntelliJ IDEA 常用快捷键一览表.md》…...

2023年全国最新道路运输从业人员精选真题及答案51

百分百题库提供道路运输安全员考试试题、道路运输从业人员考试预测题、道路安全员考试真题、道路运输从业人员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 7.A危险货物运输企业一辆载有甲醇的罐式车辆&#xff0c;在晚上…...

Baumer工业相机堡盟工业相机如何通过BGAPISDK显示Bayer彩色格式的图像(C#)

Baumer工业相机堡盟工业相机如何通过BGAPISDK显示Bayer彩色格式的图像&#xff08;C#&#xff09;Baumer工业相机Baumer工业相机的Bayer彩色图像的技术背景Baumer工业相机通过BGAPI SDK在回调函数里显示Bayer彩色图像Baumer工业相机在BufferEvent显示Bayer彩色图像Baumer工业相…...