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

设计模式 - 行为模式

行为模式

观察者模式,策略模式,命令模式,中介者模式,备忘录模式,模板方法模式,迭代器模式,状态模式,责任链模式,解释器模式,访问者模式

保存/封装 行为/请求
Strategy 模式抽象出同一的接口,执行不同的算法
Command 模式封装一个请求,从而决定何时、怎样满足请求
Visitor 模式某些可作用于一个(组)对象上的操作,但不修改这些对象的类
x对多的依赖关系
Observer 模式(一对多)对多个对象依赖于另外一个对象,而这些对象又如何保持一致
Mediator 模式(多对多)对象间怎样交互、和谁交互
组件协作
Template 模式对算法中的某些步骤
状态变化
State 模式对象的状态
Memento 模式对一个对象中哪些私有信息存放在该对象之外,以及在对什么时候进行存储
数据结构
Chain of Responsibility 模式满足一个请求的对象链
Iterator 模式如何遍历、访问一个聚合的各元素
领域问题
Interpreter 模式对一个语言的文法及解释

保存/封装 行为/请求

Strategy

结构化设计 分而治之

ifelse switch case中 if else绝对不变,可以用面相对象 抽象来解决。

code
#include <cstdio>
#include <cstdlib>class Strategy {
public:virtual ~Strategy() = default;virtual void excute() = 0;
};class Strategy_allin : public Strategy {
public:void excute() {printf("塔塔开!\n");}
};class Strategy_giveup : public Strategy {
public:void excute() {printf("点了点了点了.\n");}
};class ChasingGame {
public:void play() {if (this->mStrategy) {mStrategy->excute();} else {printf("挂机,等着输.\n");}}void set_strategy(Strategy* strategy) {if (this->mStrategy) {delete this->mStrategy;}this->mStrategy = strategy;}Strategy* mStrategy = nullptr;
};int main() {ChasingGame* mGame = new ChasingGame;mGame->play();Strategy* mStrategy = new Strategy_allin;mGame->set_strategy(mStrategy);mGame->play();mStrategy = new Strategy_giveup;mGame->set_strategy(mStrategy);mGame->play();return 1;
}
command (保存)

将 请求/行为 封装成对象。

基类 Command 虚方法 excute,子类继承后实现excute方法。到此为止的话 和策略模式特别类似,但区别是 存在一个容器(复合命令对象)存放cmd对象,执行其中所有的命令。

  • 策略模式,往往需要工厂模式创建一个对象 执行该对象的方法。

  • cmd模式,一般自行创建cmd对象,将请求放入队列中。怎么执行这个请求,是队列决定的

函数对象和cmd模式存在相似。

  • 函数对象

    • 执行函数对象是通过重载()操作符,

    • 函数对象以函数签名来定义行为接口规范,

    • 编译时绑定(泛型编程 使用模板,编译时解析类型)

      更灵活,性能更高。

  • cmd模式

    • 以面相对象的 “接口 实现”来定义行为接口规范,更严格
    • 有性能损失
    • 运行时绑定 > 编译时绑定
#include <cstdio>
#include <cstdlib>
#include <vector>class Command {
public:virtual ~Command() = default;virtual void excute() = 0; 
};class Command_EatApple : public Command {
public:void excute() {printf("eat an Apple\n");}
};class Command_DrinkTea : public Command {
public:void excute() {printf("drink a cup of tea\n");}
};class CmdQueue {
public:void enqueueCmd(Command* cmd) {this->cmds.push_back(cmd);}void handleCmd() {for (auto cmd : this->cmds) {cmd->excute();}cmds.clear();}std::vector<Command*> cmds;
};int main() {CmdQueue* mQueue = new CmdQueue;Command_DrinkTea* cmd1 = new Command_DrinkTea;Command_EatApple* cmd2 = new Command_EatApple;mQueue->enqueueCmd(cmd1);mQueue->enqueueCmd(cmd2);printf("容器决定什么时候执行cmd");mQueue->handleCmd();delete cmd1;delete cmd2;delete mQueue;return 0;
}
visitor (升维)
概念

对 Strategy模式 的维度提升——

原先,Strategy :

  • 实现处 基类定义 子类实现,一个方法 excute
  • 使用处 调用。

后来,Command:更进一步

  • 将 Strategy 视为一个可移动的对象
  • 使用处决定 执行/不执行 什么时候执行 其中的 excute 方法。

**现在,visitor :**作用与对象结构的二次辨析(dispatch)

  • 实现处同时实现多个不同的动作
  • 不同的使用处,选择执行其中一个动作

体现在使用上:

  • 实现处 visitor 类

    • 基类:要求各个方法的接口足够稳定
      • 定义若干虚函数 actionA, actionB ...
    • 子类:
      • 实现虚函数 actionA, actionB ...
  • 使用处 element类:层次结构稳定,其中面临的操作面临频繁的变化。

    • 基类 element:以下接口稳定

      • 虚函数action,不同的子类对其进行实现

      否则一旦基类element添加新的虚函数,就需要修改所有子类。

      • 方法accept(&visitor)

      接收&保存一个 visitor 对象(不用保存若干不同的 Strategy/Command 对象—— all in one)

    • 子类:要求数量稳定

      • 实现接口 action
      • 实现的方法是:调用 所保存的 visitor 对象的不同 actionX。例如
        • elementA 的方法action执行visitor.actionA
        • elementB 的方法action执行visitor.actionB
code
// 作用与对象结构的二次辨析
#include <cstdio>class Visitor {
public:virtual ~Visitor() = default;virtual void action_lunch() = 0;virtual void action_dinner() = 0;
};class Visitor_Shanghai : public Visitor {
public:virtual void action_lunch() {printf("山西午餐吃炸酱面\n");}virtual void action_dinner() {printf("山西晚餐吃刀削面\n");}
};class Visitor_ShanXi : public Visitor {
public:virtual void action_lunch() {printf("上海午餐吃酱鸭子\n");}virtual void action_dinner() {printf("上海晚餐吃剩下的酱鸭子\n");}
};class Element {
public:virtual ~Element() = default;virtual void eat_meal() = 0;virtual void accept(Visitor* visitor) {mVisitor = visitor;}Visitor* mVisitor;
};class Element_Lunch : public Element {
public:virtual void eat_meal() {if (mVisitor) {mVisitor->action_lunch();}}
};class Element_dinner : public Element {
public:virtual void eat_meal() {if (mVisitor) {mVisitor->action_dinner();}}
};int main() {Visitor* mShanxi = new Visitor_ShanXi;Visitor* mShanghai = new Visitor_Shanghai;Element* meal = new Element_Lunch;meal->accept(mShanghai);meal->eat_meal();delete meal;meal = new Element_dinner;meal->accept(mShanxi);meal->eat_meal();delete meal;delete mShanghai;delete mShanxi;return 1;
}

x对多的依赖关系

Observer 观察者模式(单向)

Observer 模式要解决的问题为:

指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变 “一”变化的时候,所有依赖于这个“一”的多对象都得到通知并被自动更新。

Subject 提供

  • 依赖于它的观察者 Observer 的

    • 注册(registerObserver)
    • 注销(remove)操作,
  • 使依赖于它的所有观察者同步的操作(notifyObserver),

观察者 Observer 提供

  • Update 操作
  • 注意这里的 Observer 的 Update 操作并不在 Observer 改变了 Subject 目标状态的时候就对自己进行更新,这个更新操作要延迟到 Subject 对象发出 Notify 通知所有Observer 进行修改(调用 Update)。
#include <cstdio>
#include <iostream>
#include <string>
#include <list>class Observer;
class Subscriber;class Subject {
public:virtual ~Subject() = default;virtual void registObserver(Observer*) = 0;virtual void removeObserver(Observer*) = 0;virtual void notifyObserver() = 0;std::list<Observer*> mObservers;
};class Subscriber {
public:Subscriber(std::string name) : name(name){};std::string name;void watchVideo() {printf("%s start watching . \n", this->name.c_str());}
};class Observer {
public:void addSubscriber(Subscriber*);void removeSubscriber(Subscriber*);void notifySubscriber();std::list<Subscriber*> mSubcribers;
};class Subject_Bilibili : public Subject {
public:virtual void registObserver(Observer* observer) {this->mObservers.push_back(observer);};virtual void removeObserver(Observer* observer) {this->mObservers.remove(observer);};virtual void notifyObserver() {printf("bilibili update! \n");for (auto observer : this->mObservers) {observer->notifySubscriber();}}
};void Observer::addSubscriber(Subscriber* subscriber) {this->mSubcribers.push_back(subscriber);
}
void Observer::removeSubscriber(Subscriber* subscriber) {this->mSubcribers.remove(subscriber);
}
void Observer::notifySubscriber() {printf("好的,这就通知\n");for (auto subscriber : this->mSubcribers) {subscriber->watchVideo();}
}int main() {Subject* biblibili = new Subject_Bilibili;Observer* mObserver = new Observer;Subscriber* A = new Subscriber("张三");Subscriber* B = new Subscriber("李四");Subscriber* C = new Subscriber("王五");biblibili->registObserver(mObserver);mObserver->addSubscriber(A);mObserver->addSubscriber(B);mObserver->addSubscriber(C);mObserver->removeSubscriber(C);biblibili->notifyObserver();return 1;
}
Mediator 中介模式(双向/多向)

Mediator 解耦系统内多个类之间需要大量密集复杂的相互交互,对他们进行集中管理。

  • 依赖倒置原则 在多对象模型中的体现
  • 类似交换机,要求 通信规范
  • 实现
    • 让这些类继承相同的接口/成为某一基类的子类
    • 子类都持有中介的指针
    • 中介持有所有子类的指针

基类成员 基类::成员名,与子类成员进行区分。

#include <cstdio>
#include <iostream>
#include <string>
#include <list>class Mediator;class Client {
public:virtual ~Client() = default;void registMediator(Mediator* mediator);void callSomeTeam(int type);virtual void responce() = 0;Mediator* mMediator;int type;std::string name;
};class Client_Boss : public Client {
public:virtual ~Client_Boss() = default;Client_Boss(std::string name, Mediator* mediator) {Client::name = name;Client::type = 99;registMediator(mediator);}virtual void responce() {printf("Boss %s here! what do u want?\n", name.c_str());}
};class Client_Engineer : public Client {
public:virtual ~Client_Engineer() = default;Client_Engineer(std::string name, Mediator* mediator) {Client::name = name;Client::type = 1;registMediator(mediator);}virtual void responce() {printf("Engineer %s here! how can i help u?\n", name.c_str());}
};class Mediator {
public:void registClient(Client* client) {this->mClient.push_back(client);}void removeClient(Client* client) {this->mClient.remove(client);}void callClient(int type) {printf("callClient type = %d \n", type);for (auto client : this->mClient) {if (client->type == type) {client->responce();}}}std::list<Client*> mClient;
};void Client::callSomeTeam(int type) {if (this->mMediator)this->mMediator->callClient(type);elseprintf("unset Mediator\n");
}void Client::registMediator(Mediator* mediator){this->mMediator = mediator;mediator->registClient(this);
}int main() {Mediator* mMediator = new Mediator;Client_Boss* mBoss = new Client_Boss("fajie", mMediator);Client_Engineer* mEngineer1 = new Client_Engineer("pengyi 1", mMediator);Client_Engineer* mEngineer2 = new Client_Engineer("pengyi 2", mMediator);mBoss->callSomeTeam(1);printf("10mins after\n");mEngineer1->callSomeTeam(99);return 1;
}

组件协作

Template 模板模式

对于某一个业务逻辑(算法实现)在不同的对象中有不同的细节实现,但是逻辑(算法)的框架(或通用的应用算法)是相同的。

Template 模式,采用继承的方式实现这一点

  • 抽象基类:

    定义细节的接口,定义逻辑(算法)框架

  • 子类

    实现逻辑细节。

    在子类实现详细的处理算法时并不会改变算法中的执行次序。

#include <iostream>
using namespace std;//做饮料模板
class TemplateDrink {
public:virtual ~TemplateDrink() = default;//煮水virtual void BoildWater() = 0;//冲泡virtual void Brew() = 0;//倒入杯中virtual void PourInCup() = 0;//加辅助材料virtual void AddSomething() = 0;//模板方法void Make() {BoildWater();Brew();PourInCup();AddSomething();}
};class Coffee : public TemplateDrink {virtual void BoildWater() {cout << "煮纯净水" << endl;}virtual void Brew() {cout << "冲泡咖啡" << endl;}virtual void PourInCup() {cout << "咖啡倒入杯中" << endl;}virtual void AddSomething() {cout << "加牛奶" << endl;}
};class Tea :public TemplateDrink {virtual void BoildWater() {cout << "煮山泉水" << endl;}virtual void Brew() {cout << "冲泡铁观音" << endl;}virtual void PourInCup() {cout << "茶水倒入杯中" << endl;}virtual void AddSomething() {}
};int main()
{Tea* tea = new Tea;tea->Make();Coffee* coffee = new Coffee;coffee->Make();delete tea;delete coffee;
}

状态变化

State 状态模式

主要解决:Switch/Case 的爆炸

Switch/Case 的缺点

  • 当状态数目很多的时候,维护一大组的Switch/Case 语句将是一件异常困难并且容易出错的事情。

  • 状态逻辑和动作实现没有分离。

  • 动作的实现代码直接写在状态的逻辑当中。

    后果是系统的扩展性和维护得不到保证。

概念
和策略模式类似

每个人、事物在不同的状态下会有不同表现(动作),而一个状态又会在不同的表现下转移到下一个不同的状态(State)。

状态机

  • 不同状态的operation,高度相似,相对固定。
  • operation依据某个变量state,发生变化。
优点

State类:枚举可能的状态,

  • 可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。

  • 封装了转换规则。在枚举状态之前需要确定状态种类。

Process:将所有与某个状态有关的行为放到一个类中,

  • 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。

系统资源

  • 通常与单例模式一起使用
  • 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
实现上

State

  • State基类 除虚析构外,还持有

    • 一系列operation虚函数
    • 看情况
      • process指针(使用该指针,更改process中的下一个state)
      • state指针(指向下一个状态),(上下文指针)
  • State子类继承State基类

    • 重写operarion函数。

Process

  • Process 基类

    • 持有State指针
    • 一系列operation虚函数。
  • Process 子类

    • 重写operation

    • 调用State指针的operation

      让State更新为下一个状态 state = state->next。

code
// main.cpp#include <cstdio>
#include <cstdlib>
#include "processImpl.cpp"
#include "stateImpl.cpp"int main() {Process* mProcess = new Process(10);mProcess->buy(101);mProcess->buy(1);mProcess->recharge(10);mProcess->buy(1);mProcess->recharge(1000);mProcess->buy(100);delete mProcess;return 1;
}
// process.h#include <cstdio>
#include <cstdlib>
#include "state.h"
#pragma onceclass Process {
public:Process(int = 10);void set_state(State* state);void recharge(int money);void buy(int price);int query_money();int balance;State* mState = nullptr;
};
// processImpl.cpp#include "process.h"
#include "state.h"
#include <cstdio>
#pragma onceProcess::Process(int init_money) {this->balance = init_money;if (init_money > 0) {this->set_state(new State_rich);} else {this->set_state(new State_poor);}
}int Process::query_money() {return this->balance;
}void Process::set_state(State* state) {if (mState)delete this->mState;this->mState = state;this->mState->set_process(this);
}void Process::recharge(int money) {bool result = this->mState->recharge(money);this->balance += money;if (result) {printf("尊贵的用户: 充值后,余额 %d\n", this->query_money());} else {printf("欠费的用户: 充值后,余额 %d\n", this->query_money());}
}void Process::buy(int price) {if (this->mState->buy(price))printf("购买成功, 余额 %d\n", this->query_money());elseprintf("购买失败 请充值, 余额 %d\n", this->query_money());
}
// state.h
#include <cstdio>
#include <cstdlib>
#pragma once
class Process;class State {
public:virtual ~State() = default;void set_process(Process* process) {this->process = process;}Process* get_process() {return this->process;}virtual bool buy(int) = 0; virtual bool recharge(int) = 0; Process* process;
};class State_rich : public State {
public:bool buy(int) override;bool recharge(int) override;
};class State_poor : public State {
public:bool buy(int) override;bool recharge(int) override;
};
// stateImpl.cpp#include <cstdio>
#include <cstdlib>
#include "state.h"
#include "process.h"
#pragma oncebool State_rich::buy(int price) {this->process->balance -= price;int balance = this->process->query_money();if (balance <= 0) {this->process->set_state(new State_poor);}return true;
}bool State_rich::recharge(int money) {int balance = this->process->query_money();if (money + balance > 0) {return true;}return false;
}bool State_poor::buy(int price) {// int balance = this->process->query_money();return false;
}bool State_poor::recharge(int money) {int balance = this->process->query_money();if (money + balance > 0) {this->process->set_state(new State_rich);return true;}return false;
}
Memento (过时)

Memento 备忘录模式

信息隐藏条件下,对对象的快照。

原发器,持有state,保存快照时 根据state创建并返回一个memnto对象。恢复时,传入memnto对象,设置 原发器的state对象。 实现对原发器对外的信息隐藏。

现在来看太低级了 java c#等具有高效成熟容易正确实现的对象序列化支持,有更容易正确实现的序列化方案

不怎么介绍也没关系

迭代器

从性能角度讲——编译期多态好过运行时多态

  • 泛型编程的迭代器 > 面相对象的迭代器

  • 虚函数成本过高

但在 java c# php等等语言,不支持编译时多态,仍然在使用运行时多态

责任链模式

运行时的类型判断。一个请求者可能有多个接受者,但最后真正的接受者或者说处理者只有一个。运行时动态添加 修改请求的处理职责。

避免请求的发送者和接受者之间的耦合关系。

数据结构构成的处理模型。链表

行为变化,将组件的行为与组件本身进行解耦

非虚函数,静态函数 地址在编译时绑定的方式。

虚函数是运行时,使用虚函数表指针绑定的。

Interpreter 模式

对一个语言的文法及解释

相关文章:

设计模式 - 行为模式

行为模式 观察者模式&#xff0c;策略模式&#xff0c;命令模式&#xff0c;中介者模式&#xff0c;备忘录模式&#xff0c;模板方法模式&#xff0c;迭代器模式&#xff0c;状态模式&#xff0c;责任链模式&#xff0c;解释器模式&#xff0c;访问者模式 保存/封装 行为/请求…...

InstructGPT的四阶段:预训练、有监督微调、奖励建模、强化学习涉及到的公式解读

1. 预训练 1. 语言建模目标函数&#xff08;公式1&#xff09;&#xff1a; L 1 ( U ) ∑ i log ⁡ P ( u i ∣ u i − k , … , u i − 1 ; Θ ) L_1(\mathcal{U}) \sum_{i} \log P(u_i \mid u_{i-k}, \dots, u_{i-1}; \Theta) L1​(U)i∑​logP(ui​∣ui−k​,…,ui−1​;Θ…...

没有HTTPS 证书时,像这样实现多路复用

在没有 HTTPS 证书的情况下,HTTP/2 通常不能直接通过 HTTP 协议使用。虽然 HTTP/2 协议的规范是可以支持纯 HTTP 连接(即通过 http:// 协议),但大多数主流浏览器(如 Chrome、Firefox)都 强制要求 HTTP/2 必须在 HTTPS 上运行。这是出于安全和隐私的考虑。 因此,如果你没…...

2.1.ReactOS系统NtReadFile函数的实现。

ReactOS系统NtReadFile函数的实现。 ReactOS系统NtReadFile函数的实现。 文章目录 ReactOS系统NtReadFile函数的实现。NtReadFile函数的定义NtReadFile函数的实现 NtReadFile()是windows的一个系统调用&#xff0c;内核中有一个叫NtReadFile的函数 NtReadFile函数的定义 NTS…...

2020-11-06《04丨人工智能时代,新的职业机会在哪里?》

《香帅中国财富报告25讲》 04丨人工智能时代&#xff0c;新的职业机会在哪里&#xff1f; 1、新机会的三个诞生方向 前两讲我们都在说&#xff0c;人工智能的出现会极大地冲击现有的职业&#xff0c;从2020年开始&#xff0c;未来一二十年&#xff0c;可能有一半以上的职业都会…...

TensorRT-LLM七日谈 Day5

模型加载 在day2, 我们尝试了对于llama8B进行转换和推理&#xff0c;可惜最后因为OOM而失败&#xff0c;在day4,我们详细的过了一遍tinyllama的推理&#xff0c;值得注意的是&#xff0c;这两个模型的推理走的是不同的流程。llama8b需要显式的进行模型的转换&#xff0c;引擎的…...

使用Java Socket实现简单版本的Rpc服务

通过如下demo&#xff0c;希望大家可以快速理解RPC的简单案例。如果对socket不熟悉的话可以先看下我的上篇文章 Java Scoket实现简单的时间服务器-CSDN博客 对socket现有基础了解。 RPC简介 RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;是一种…...

P2P 网络 简单研究 1

起因&#xff0c; 目的: P2P 网络&#xff0c; 一道题。题目描述&#xff0c; 在下面。 P2P 网络&#xff0c;我以前只是听说过&#xff0c;并不深入。如果我有5台电脑的话&#xff0c;我也想深入研究一下。 P2P 简介: P2P&#xff08;Peer-to-Peer&#xff09;网络是一种分…...

RAG(检索增强生成)面经(1)

1、RAG有哪几个步骤&#xff1f; 1.1、文本分块 第一个步骤是文本分块&#xff08;chunking&#xff09;&#xff0c;这是一个重要的步骤&#xff0c;尤其在构建与处理文档的大型文本的时候。分块作为一种预处理技术&#xff0c;将长文档拆分成较小的文本块&#xff0c;这些文…...

卫爱守护|守护青春,送出温暖

2024年10月10日&#xff0c;艾多美爱心志愿者来到校园。艾多美“卫艾守护”项目于吉林省白山市政务大厅会议室举办了捐赠仪式&#xff0c;东北区外事部经理黄山出席了捐赠仪式仪式&#xff0c;为全校女同学捐赠了青春关爱包。 此次捐赠&#xff0c;面向吉林省自山市第十八中学、…...

ubuntu-24.04.1 系统安装

使用VMware虚拟机上进行实现 官网下载地址&#xff1a; https://cn.ubuntu.com/download https://releases.ubuntu.com 操作系统手册&#xff1a; https://ubuntu.com/server/docs/ &#xff08;里面包含安装文档&#xff09; 安装指南&#xff08;详细&#xff09;&#xff1a…...

华为OD机试真题---生成哈夫曼树

华为OD机试中关于生成哈夫曼树的题目通常要求根据给定的叶子节点权值数组&#xff0c;构建一棵哈夫曼树&#xff0c;并按照某种遍历方式&#xff08;如中序遍历&#xff09;输出树中节点的权值序列。以下是对这道题目的详细解析和解答思路&#xff1a; 一、题目要求 给定一个…...

小红书新ID保持项目StoryMaker,面部特征、服装、发型和身体特征都能保持一致!(已开源)

继之前和大家介绍的小红书在ID保持以及风格转换方面相关的优秀工作&#xff0c;感兴趣的小伙伴可以点击以下链接阅读~ 近期&#xff0c;小红书又新开源了一款文生图身份保持项目&#xff1a;StoryMaker&#xff0c;是一种个性化解决方案&#xff0c;它不仅保留了面部的一致性&…...

Docker 环境下 GPU 监控实战:使用 Prometheus 实现 DCGM Exporter 部署与 GPU 性能监控

Docker 环境下 GPU 监控实战&#xff1a;使用 Prometheus 实现 DCGM Exporter 部署与 GPU 性能监控 文章目录 Docker 环境下 GPU 监控实战&#xff1a;使用 Prometheus 实现 DCGM Exporter 部署与 GPU 性能监控一 查看当前 GPU 信息二 dcgm-exporter 部署1&#xff09;Docker r…...

联想小新打印机M7328w如何解决卡纸,卡了一个小角在里面,然后再次打印的时候,直接卡住,不能动了。灯显示红色。

1、今天打印一张纸&#xff0c;应该是不小心放歪了&#xff0c;打出来的也是有些斜&#xff0c;然后打出来缺少了个角。 图中的小纸就是从打印机的左边的角&#xff0c;用镊子取出来的&#xff0c;手不太好拿&#xff0c;所以拿个工具比较合适。 2、那么碰到这种卡纸应该如何处…...

软件可靠性之MTTR、MTBF、MTTF、MTTD区别

一.概念解释 1.MTBF&#xff08;Mean Time Between Failures&#xff09;&#xff1a;指两次故障之间的平均时间&#xff0c;通常用于衡量设备或系统的可靠性。 2.MTTF&#xff08;Mean Time to Failure&#xff09;&#xff1a;指设备或系统的平均无故障运行时间。 3.MTTR&am…...

Qt-QDockWidget浮动窗口相关操作(49)

目录 描述 使用 描述 在 Qt 中&#xff0c;浮动窗⼝也称之为铆接部件。浮动窗⼝是通过 QDockWidget类 来实现浮动的功能。浮动窗口⼀般是位于核心部件的周围&#xff0c;可以有多个。 使用 创建我们可以参考下面的语法格式 使用起来也很简单&#xff0c;不过只能创建一个 Q…...

图形用户界面-GUI的基本概念和组件之一

前言 GUI&#xff08;Graphical User Interface&#xff0c;图形用户界面&#xff0c;简称图形界面&#xff09;编程实际是引用java.awt或javax.swing类包中的窗口类、控制组件类、布局类、事件类等&#xff0c;通过将控制组件类&#xff0c;如菜单、按钮、文本框等&#xff0c…...

【MATLAB代码】基于RSSI原理的蓝牙定位程序(N个锚点、三维空间),源代码可直接复制

文章目录 介绍主要功能技术细节适用场景程序结构运行截图源代码详细教程:基于RSSI的蓝牙定位程序1. 准备工作2. 代码结构2.1 清理工作环境2.2 定义参数2.3 生成锚点坐标2.4 定义信号强度与距离的关系2.5 模拟未知点的位置2.6 定位函数2.7 绘图2.8 输出结果2.9 定义定位函数3. …...

Pyenv 介绍和安装指南 - Ubuntu 24

原文&#xff1a; https://www.qiulin-dev.top/articles/81aab753-0d0e-470c-b08f-2643c876841b 1. Pyenv 介绍 Pyenv 是一个非常流行的 Python 版本管理工具&#xff0c;它可以让你在同一台机器上安装并管理多个不同的 Python 版本&#xff0c;解决了不同项目需要不同 Python…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

职坐标物联网全栈开发全流程解析

物联网全栈开发涵盖从物理设备到上层应用的完整技术链路&#xff0c;其核心流程可归纳为四大模块&#xff1a;感知层数据采集、网络层协议交互、平台层资源管理及应用层功能实现。每个模块的技术选型与实现方式直接影响系统性能与扩展性&#xff0c;例如传感器选型需平衡精度与…...

ES海量数据更新及导入导出备份

一、根据查询条件更新字段 from elasticsearch import Elasticsearch import redis import json# 替换下面的用户名、密码和Elasticsearch服务器地址 username elastic password password es_host https://127.0.0.2:30674# 使用Elasticsearch实例化时传递用户名和密码 es…...

1.springmvc基础入门(一)

1.Spring MVC概念 Spring MVC 是 Spring Framework 提供的 Web 组件&#xff0c;全称是 Spring Web MVC&#xff0c;是⽬前主流的实现 MVC 设计模式的框架&#xff0c;提供前端路由映射、视图解析等功能。 Java Web 开发者必须要掌握的技术框架。 2.Spring MVC 功能 MVC&am…...