03-行为型模式(共10种)

上一篇: 02-结构型设计模式(共7种)


1. Strategy(策略模式)

        策略模式是一种行为型设计模式,它定义了一系列算法,将每个算法封装到独立的类中,并使它们可以互相替换。这样可以使算法的变化独立于使用算法的客户端。

        在 C++ 中,策略模式通常涉及以下几个角色:

        ①. Strategy(策略接口):定义了所有支持的算法的通用接口。

        ②. ConcreteStrategy(具体策略类):实现了策略接口,提供了具体的算法实现。

        ③. Context(上下文):维护一个对策略对象的引用,并在需要时调用策略对象的方法

        以下是模式示例:

#include <iostream>// 策略接口
class Strategy {
public:virtual void execute() = 0;
};// 具体策略类A
class ConcreteStrategyA : public Strategy {
public:void execute() override {std::cout << "Executing Strategy A" << std::endl;}
};// 具体策略类B
class ConcreteStrategyB : public Strategy {
public:void execute() override {std::cout << "Executing Strategy B" << std::endl;}
};// 上下文类
class Context {
private:Strategy* strategy;public:Context(Strategy* strat) : strategy(strat) {}void setStrategy(Strategy* strat) {strategy = strat;}void executeStrategy() {strategy->execute();}
};int main() {ConcreteStrategyA strategyA;ConcreteStrategyB strategyB;Context context(&strategyA);context.executeStrategy();context.setStrategy(&strategyB);context.executeStrategy();return 0;
}

2. Observer(观察者模式)

        观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这种模式也被称为:发布-订阅(Publish-Subscribe)模式

        在 C++ 中,观察者模式通常涉及以下几个角色:

        ①. Subject(主题):定义了一个接口,用于添加、删除和通知观察者对象

        ②. ConcreteSubject(具体主题):实现了主题接口,并维护了观察者对象的列表,可以对观察者进行增加、删除和通知操作。

        ③. Observer(观察者):定义了一个接口,用于接收主题对象的通知。

        ④. ConcreteObserver(具体观察者):实现了观察者接口,并在接收到通知时执行相应的操作。

        以下是模式示例:

#include <iostream>
#include <vector>// 观察者接口
class Observer {
public:virtual void update(const std::string& message) = 0;
};// 具体观察者A
class ConcreteObserverA : public Observer {
public:void update(const std::string& message) override {std::cout << "Concrete Observer A received message: " << message << std::endl;}
};// 具体观察者B
class ConcreteObserverB : public Observer {
public:void update(const std::string& message) override {std::cout << "Concrete Observer B received message: " << message << std::endl;}
};// 主题接口
class Subject {
protected:std::vector<Observer*> observers;public:virtual void attach(Observer* observer) {observers.push_back(observer);}virtual void detach(Observer* observer) {observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());}virtual void notify(const std::string& message) {for (Observer* observer : observers) {observer->update(message);}}
};// 具体主题
class ConcreteSubject : public Subject {
public:void doSomething(const std::string& message) {std::cout << "Subject is doing something..." << std::endl;notify(message);}
};int main() {ConcreteObserverA observerA;ConcreteObserverB observerB;ConcreteSubject subject;subject.attach(&observerA);subject.attach(&observerB);subject.doSomething("Hello observers!");subject.detach(&observerA);subject.doSomething("Hello again, with one less observer!");return 0;
}

3. Template Method(模板方法模式)

        模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,将算法的具体步骤延迟到子类中实现。模板方法模式通过把不变行为放在父类中,将可变行为放在子类中,实现了代码复用和灵活性的结合

        在 C++ 中,模板方法模式通常涉及以下几个角色:

        ①. AbstractClass(抽象类):定义了一个模板方法,其中包含了算法的骨架,该方法可以包含若干抽象方法和具体方法。

        ②. ConcreteClass(具体类):继承自抽象类,实现了抽象方法,完成算法的具体步骤。

        以下是模式示例:

#include <iostream>// 抽象类
class AbstractClass {
public:// 模板方法void templateMethod() {primitiveOperation1();primitiveOperation2();concreteOperation();hook(); // 可选的钩子方法}// 抽象方法1virtual void primitiveOperation1() = 0;// 抽象方法2virtual void primitiveOperation2() = 0;// 具体方法void concreteOperation() {std::cout << "Concrete Operation" << std::endl;}// 钩子方法(可选实现)virtual void hook() {std::cout << "Default Hook Method" << std::endl;}
};// 具体类A
class ConcreteClassA : public AbstractClass {
public:void primitiveOperation1() override {std::cout << "Concrete Class A - Primitive Operation 1" << std::endl;}void primitiveOperation2() override {std::cout << "Concrete Class A - Primitive Operation 2" << std::endl;}void hook() override {std::cout << "Concrete Class A - Custom Hook Method" << std::endl;}
};// 具体类B
class ConcreteClassB : public AbstractClass {
public:void primitiveOperation1() override {std::cout << "Concrete Class B - Primitive Operation 1" << std::endl;}void primitiveOperation2() override {std::cout << "Concrete Class B - Primitive Operation 2" << std::endl;}
};int main() {AbstractClass* objA = new ConcreteClassA();AbstractClass* objB = new ConcreteClassB();objA->templateMethod();std::cout << std::endl;objB->templateMethod();delete objB;delete objA;return 0;
}

4. Command(命令模式)

        命令模式是一种行为型设计模式,它将请求封装为一个对象,从而允许用不同的请求来参数化客户端对象,并且能够支持队列、日志和可撤销的操作。命令模式的核心思想是将请求的发送者和接收者解耦,使得请求发送者只需知道如何发送请求,而不需要知道接收者的具体操作

在 C++ 中,命令模式通常涉及以下几个角色:

        ①. Command(命令接口):定义了执行请求的接口,通常包含一个执行方法 execute()。

        ②. ConcreteCommand(具体命令类):实现了命令接口,负责执行具体的操作。

        ③. Receiver(接收者):负责实际执行命令的对象。

        ④. Invoker(调用者):持有命令对象,并在需要时调用命令对象的执行方法。

        以下是模式示例:

#include <iostream>// 命令接口
class Command {
public:virtual void execute() = 0;
};// 具体命令类A
class ConcreteCommandA : public Command {
private:std::string receiverState; // 接收者状态Receiver* receiver; // 接收者对象public:ConcreteCommandA(Receiver* rec, const std::string& state) : receiver(rec), receiverState(state) {}void execute() override {std::cout << "Concrete Command A executed." << std::endl;receiver->action(receiverState);}
};// 具体命令类B
class ConcreteCommandB : public Command {
private:Receiver* receiver; // 接收者对象public:ConcreteCommandB(Receiver* rec) : receiver(rec) {}void execute() override {std::cout << "Concrete Command B executed." << std::endl;receiver->action("B");}
};// 接收者
class Receiver {
public:void action(const std::string& state) {std::cout << "Receiver performing action with state: " << state << std::endl;}
};// 调用者
class Invoker {
private:Command* command;public:Invoker(Command* cmd) : command(cmd) {}void setCommand(Command* cmd) {command = cmd;}void executeCommand() {command->execute();}
};int main() {Receiver receiver;ConcreteCommandA commandA(&receiver, "A");ConcreteCommandB commandB(&receiver);Invoker invoker(&commandA);invoker.executeCommand();invoker.setCommand(&commandB);invoker.executeCommand();return 0;
}

5. Chain of Responsibility(责任链模式)

        责任链模式是一种行为型设计模式,它允许将请求沿着处理链传递,并且在链上的每个处理者都有机会处理请求或将其传递给下一个处理者。这种模式可以避免请求发送者和接收者之间的直接耦合,并支持动态添加或修改处理者

        在 C++ 中,责任链模式通常涉及以下几个角色:

        ①. Handler(处理者接口):定义了处理请求的接口,并包含一个对下一个处理者的引用

        ②. ConcreteHandler(具体处理者类):实现了处理者接口,并对请求进行具体处理或将请求传递给下一个处理者

        以下是模式示例:

#include <iostream>// 处理者接口
class Handler {
protected:Handler* nextHandler;public:Handler() : nextHandler(nullptr) {}void setNextHandler(Handler* handler) {nextHandler = handler;}virtual void handleRequest(int request) = 0;
};// 具体处理者A
class ConcreteHandlerA : public Handler {
public:void handleRequest(int request) override {if (request >= 0 && request < 10) {std::cout << "Concrete Handler A handles the request." << std::endl;} else if (nextHandler != nullptr) {nextHandler->handleRequest(request);}}
};// 具体处理者B
class ConcreteHandlerB : public Handler {
public:void handleRequest(int request) override {if (request >= 10 && request < 20) {std::cout << "Concrete Handler B handles the request." << std::endl;} else if (nextHandler != nullptr) {nextHandler->handleRequest(request);}}
};// 客户端
int main() {ConcreteHandlerA handlerA;ConcreteHandlerB handlerB;handlerA.setNextHandler(&handlerB);handlerA.handleRequest(5);handlerA.handleRequest(15);handlerA.handleRequest(25);return 0;
}

6. State(状态模式)

        状态模式是一种行为型设计模式,它允许对象在其内部状态发生改变时改变其行为,使得对象看起来好像修改了其类。状态模式将对象的行为封装在不同的状态类中,并将状态的改变委托给当前状态对象,从而实现了状态之间的切换和行为的动态变化

        在 C++ 中,状态模式通常涉及以下几个角色:

        ①. State(状态接口):定义了一个接口,用于封装与特定状态相关的行为。

        ②. ConcreteState(具体状态类):实现了状态接口,并实现了与特定状态相关的行为。

        ③. Context(上下文类):维护一个对当前状态对象的引用,并将状态的改变委托给当前状态对象

        以下是模式示例:

#include <iostream>// 状态接口
class State {
public:virtual void handle() = 0;
};// 具体状态类A
class ConcreteStateA : public State {
public:void handle() override {std::cout << "Concrete State A handled." << std::endl;}
};// 具体状态类B
class ConcreteStateB : public State {
public:void handle() override {std::cout << "Concrete State B handled." << std::endl;}
};// 上下文类
class Context {
private:State* currentState;public:Context(State* initState) : currentState(initState) {}void setState(State* newState) {currentState = newState;}void request() {currentState->handle();}
};int main() {ConcreteStateA stateA;ConcreteStateB stateB;Context context(&stateA);context.request();context.setState(&stateB);context.request();return 0;
}

7. Visitor(访问者模式)

        访问者模式是一种行为型设计模式,它能够在不改变元素类(数据结构)本身的前提下,定义作用于这些元素对象的新操作。访问者模式将数据结构与作用于数据结构上的操作解耦,使得操作可以独立变化,同时也增加了新操作的扩展性。

        在 C++ 中,访问者模式通常涉及以下几个角色:

        ①. Visitor(访问者接口):定义了对各种元素对象的访问操作

        ②. ConcreteVisitor(具体访问者类):实现了访问者接口,对每种元素对象的访问操作进行具体实现。

        ③. Element(元素接口):定义了接受访问者对象访问的方法。

        ④. ConcreteElement(具体元素类):实现了元素接口,并实现了接受访问者对象访问的方法。

        ⑤. ObjectStructure(对象结构):维护了一个元素对象的集合,并提供了遍历集合并接受访问者对象访问的方法

        以下是模式示例:

#include <iostream>
#include <vector>// 前置声明
class ConcreteVisitor;// 元素接口
class Element {
public:virtual void accept(ConcreteVisitor& visitor) = 0;
};// 具体元素类A
class ConcreteElementA : public Element {
public:void accept(ConcreteVisitor& visitor) override;std::string operationA() const;
};// 具体元素类B
class ConcreteElementB : public Element {
public:void accept(ConcreteVisitor& visitor) override;int operationB() const;
};// 访问者接口
class Visitor {
public:// 定义了对各种元素对象的访问操作virtual void visit(ConcreteElementA& element) = 0;virtual void visit(ConcreteElementB& element) = 0;
};// 具体访问者类
class ConcreteVisitor : public Visitor {
public:void visit(ConcreteElementA& element) override {std::cout << "Concrete Visitor visits " << element.operationA() << std::endl;}void visit(ConcreteElementB& element) override {std::cout << "Concrete Visitor visits " << element.operationB() << std::endl;}
};// 具体元素A的接受访问者方法实现
void ConcreteElementA::accept(ConcreteVisitor& visitor) {visitor.visit(*this);
}// 具体元素A的操作
std::string ConcreteElementA::operationA() const {return "Element A";
}// 具体元素B的接受访问者方法实现
void ConcreteElementB::accept(ConcreteVisitor& visitor) {visitor.visit(*this);
}// 具体元素B的操作
int ConcreteElementB::operationB() const {return 123;
}// 对象结构类
class ObjectStructure {
private:std::vector<Element*> elements;public:void addElement(Element* element) {elements.push_back(element);}void accept(ConcreteVisitor& visitor) {for (Element* element : elements) {element->accept(visitor);}}
};int main() {ConcreteElementA elementA;ConcreteElementB elementB;ObjectStructure structure;structure.addElement(&elementA);structure.addElement(&elementB);ConcreteVisitor visitor;structure.accept(visitor);return 0;
}

8. Memento(备忘录模式)

        备忘录模式是一种行为型设计模式,它允许在不破坏封装性的前提下捕获对象的内部状态,并在对象之外保存这个状态。备忘录模式通常用于需要记录和恢复对象状态的场景,比如撤销操作。

        在 C++ 中,备忘录模式通常涉及以下几个角色:

        ①. Originator(原发器):负责创建备忘录对象,并在需要时恢复对象状态

        ②. Memento(备忘录):用于存储原发器对象的内部状态,可以包含多个状态属性。

        ③. Caretaker(负责人):负责保存备忘录对象,但不应该修改备忘录对象的状态

        以下是模式示例:

#include <iostream>
#include <string>// 备忘录类
class Memento {
private:std::string state;public:Memento(const std::string& s) : state(s) {}std::string getState() const {return state;}
};// 原发器类
class Originator {
private:std::string state;public:void setState(const std::string& s) {state = s;}std::string getState() const {return state;}Memento createMemento() const {return Memento(state);}void restoreMemento(const Memento& m) {state = m.getState();}
};// 负责人类
class Caretaker {
private:Memento memento;public:void setMemento(const Memento& m) {memento = m;}Memento getMemento() const {return memento;}
};int main() {Originator originator;Caretaker caretaker;// 设置原发器状态originator.setState("State 1");std::cout << "Current State: " << originator.getState() << std::endl;// 创建备忘录并保存caretaker.setMemento(originator.createMemento());// 修改原发器状态originator.setState("State 2");std::cout << "Modified State: " << originator.getState() << std::endl;// 恢复备忘录状态originator.restoreMemento(caretaker.getMemento());std::cout << "Restored State: " << originator.getState() << std::endl;return 0;
}

9. Mediator(中介者模式)

        中介者模式是一种行为型设计模式,它通过引入一个中介者对象来减少多个对象之间的直接通信,并且使得这些对象不需要显式地相互引用,从而降低了对象之间的耦合度。中介者模式通常用于处理多个对象之间的复杂交互关系,将这些关系集中管理,使得系统更易于维护和扩展。

在 C++ 中,中介者模式通常涉及以下几个角色:

        ①. Mediator(中介者接口):定义了各个同事对象之间通信的接口。

        ②. ConcreteMediator(具体中介者类):实现了中介者接口,并负责协调各个同事对象之间的通信

        ③. Colleague(同事类):定义了抽象同事类的接口,每个同事对象都应该持有一个对中介者对象的引用

        ④. ConcreteColleague(具体同事类):实现了同事类接口,并在需要时与中介者对象进行通信。

        以下是模式示例:

#include <iostream>
#include <string>// 前置声明
class Colleague;// 中介者接口
class Mediator {
public:virtual void sendMessage(const std::string& message, Colleague* colleague) = 0;
};// 具体中介者类
class ConcreteMediator : public Mediator {
private:Colleague* colleagueA;Colleague* colleagueB;public:void setColleagueA(Colleague* colleague) {colleagueA = colleague;}void setColleagueB(Colleague* colleague) {colleagueB = colleague;}void sendMessage(const std::string& message, Colleague* colleague) override {if (colleague == colleagueA) {colleagueB->receiveMessage(message);} else if (colleague == colleagueB) {colleagueA->receiveMessage(message);}}
};// 同事类接口
class Colleague {
protected:Mediator* mediator;public:Colleague(Mediator* med) : mediator(med) {}virtual void sendMessage(const std::string& message) = 0;virtual void receiveMessage(const std::string& message) = 0;
};// 具体同事类A
class ConcreteColleagueA : public Colleague {
public:ConcreteColleagueA(Mediator* med) : Colleague(med) {}void sendMessage(const std::string& message) override {mediator->sendMessage(message, this);}void receiveMessage(const std::string& message) override {std::cout << "Concrete Colleague A received message: " << message << std::endl;}
};// 具体同事类B
class ConcreteColleagueB : public Colleague {
public:ConcreteColleagueB(Mediator* med) : Colleague(med) {}void sendMessage(const std::string& message) override {mediator->sendMessage(message, this);}void receiveMessage(const std::string& message) override {std::cout << "Concrete Colleague B received message: " << message << std::endl;}
};int main() {ConcreteMediator mediator;ConcreteColleagueA colleagueA(&mediator);ConcreteColleagueB colleagueB(&mediator);mediator.setColleagueA(&colleagueA);mediator.setColleagueB(&colleagueB);colleagueA.sendMessage("Hello from Colleague A");colleagueB.sendMessage("Hello from Colleague B");return 0;
}

10. Interpreter(解释器模式)

        解释器模式是一种行为型设计模式,它用于定义一个语言的文法,并提供一种解释器来解释该语言中的句子。解释器模式通常用于处理复杂的语法或规则,将这些语法或规则表示为一个抽象语法树,并通过解释器来执行对应的操作。

        在 C++ 中,解释器模式通常涉及以下几个角色:

        ①. AbstractExpression(抽象表达式):定义了一个抽象的解释操作,通常包含一个解释方法 interpret()

        ②. TerminalExpression(终结符表达式):实现了抽象表达式接口,并负责解释语言中的终结符。

        ③. NonterminalExpression(非终结符表达式):实现了抽象表达式接口,并负责解释语言中的非终结符,通常是一个复合表达式

        ④. Context(环境类):包含解释器需要的全局信息,通常由解释器来操作。

        以下是模式示例:

#include <iostream>
#include <string>
#include <unordered_map>// 环境类
class Context {
private:std::unordered_map<std::string, int> variables;public:void setVariable(const std::string& var, int value) {variables[var] = value;}int getVariable(const std::string& var) const {if (variables.find(var) != variables.end()) {return variables.at(var);}return 0; // 默认返回0}
};// 抽象表达式类
class AbstractExpression {
public:virtual int interpret(Context& context) = 0;
};// 终结符表达式类
class TerminalExpression : public AbstractExpression {
private:std::string variable;public:TerminalExpression(const std::string& var) : variable(var) {}int interpret(Context& context) override {return context.getVariable(variable);}
};// 非终结符表达式类
class NonterminalExpression : public AbstractExpression {
private:AbstractExpression* expressionA;AbstractExpression* expressionB;public:NonterminalExpression(AbstractExpression* expA, AbstractExpression* expB): expressionA(expA), expressionB(expB) {}int interpret(Context& context) override {return expressionA->interpret(context) + expressionB->interpret(context);}
};int main() {Context context;context.setVariable("a", 5);context.setVariable("b", 10);AbstractExpression* expression = new NonterminalExpression(new TerminalExpression("a"), new TerminalExpression("b"));int result = expression->interpret(context);std::cout << "Result: " << result << std::endl;delete expression;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/13453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20-LINUX--网络编程

一. 主机字节序列和网络字节序列 主机字节序列分为大端字节序和小端字节序&#xff0c;不同的主机采用的字节序列可能不同。大 端字节序是指一个整数的高位字节存储在内存的低地址处&#xff0c;低位字节存储在内存的高地址 处。小端字节序则是指整数的高位字节存储在内存的高…

保温杯盖一般是什么材质的?

保温杯盖一般是什么材质的&#xff1f; Pi材料&#xff0c;也称为聚酰亚胺&#xff08;Polyimide&#xff09;&#xff0c;具有多种特殊性能和应用领域&#xff0c;主要作用如下&#xff1a; 1. 高温耐性&#xff1a;Pi材料具有出色的高温稳定性&#xff0c;能够在高温环境下长…

国内常用的项目管理软件有哪些?六大企业级项目管理软件大盘点

一、 奥博思 PowerProject 项目管理软件 官方网址&#xff1a;http://www.powerproject.com.cn 北京奥博思软件技术有限公司自成立以来&#xff0c;一直专注于企业级项目管理软件的开发及解决方案&#xff0c;致力于为各类企业&#xff08;制造业、IT交付、金融、汽车及汽车零…

供应链投毒预警 | 开源供应链投毒202404月报发布(含投毒案例分析)

概述 悬镜供应链安全情报中心通过持续监测全网主流开源软件仓库&#xff0c;结合程序动静态分析方式对潜在风险的开源组件包进行动态跟踪和捕获&#xff0c;发现大量的开源组件恶意包投毒攻击事件。在2024年4月份&#xff0c;悬镜供应链安全情报中心在NPM官方仓库&#xff08;…

什么是检索增强生成(Retrieval Augmented Generation)?RAG 架构如何实现?

检索增强生成&#xff08;Retrieval Augmented Generation&#xff09;时代 在不断发展的生成人工智能世界中&#xff0c;检索增强生成 (RAG) 标志着一项重大进步&#xff0c;它将检索模型的准确性与生成模型的创造性相结合&#xff0c;达到了准确&创新的更高层级。 这种…

Nginx 7层负载均衡的搭建

目录 负载均衡的理解 修改配置文件 测试 1. 选择在 DMZ 区测试&#xff0c;使用 db 服务器进行测试 2.选择在外网测试负载均衡效果 负载均衡的理解 负载均衡&#xff1a;load balancer&#xff0c;简称LB Nginx 既是一个 web 服务器软件&#xff0c;也是一个负载均衡软件&a…

【NLP】文本分类

n-gram 的局限性 n-gram 只能对于填空这样的通顺性问题做出推测&#xff0c;但是没有办法完全解决句子的语义问题&#xff0c;从而无法实现文本的分类 文本的分类&#xff0c;就是将文本在语义的理解下划分到特定的主题下 手工规则 如一些垃圾过滤系统&#xff0c;需要人工制…

企业或者个体户为什么会经营异常?

在复杂多变的市场经济环境中&#xff0c;无论是企业还是个体工商户&#xff0c;都可能遭遇经营异常的情况。及时识别这些预警信号并采取有效措施&#xff0c;对于避免潜在风险、保持健康发展至关重要。本文将深入探讨企业与个体户常见的经营异常类型、识别方法以及应对策略&…

有趣的css - 文字隐身术效果

大家好&#xff0c;我是 Just&#xff0c;这里是「设计师工作日常」&#xff0c;今天分享的是利用动画属性来模拟文字隐身消失的效果。 《有趣的css》系列最新实例通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样…

php解密工具

在线编辑器 复制如下代码到空白地区: <?php namespace FatSmallTools; class NavicatPassword {protected $version 0;protected $aesKey libcckeylibcckey;protected $aesIv libcciv libcciv ;protected $blowString 3DC5CA39;protected $blowKey null;protected $b…

MCULCD屏驱动方法

MCULCD屏驱动方式 一、LCD简介二、直接采用8080时序驱动LCD三、采用FSMC&#xff08;模拟8080时序&#xff09;驱动LCD1&#xff0c;FSMC简介2&#xff0c;结构框图3&#xff0c;FMC 驱动 LCD 显示配置步骤 一、LCD简介 Liquid Crystal Display&#xff0c;即液晶显示器&#…

GPT-4o 的商业化落地使用场景

今天我想和大家聊一聊 OpenAI 的 GPT-4o。这款令人惊叹的语言模型不仅在技术层面上令人钦佩&#xff0c;也在多种实际应用中展现了巨大的商业潜力。 GPT-4o 是什么&#xff1f; 首先&#xff0c;简单介绍一下 GPT-4o。它是由 OpenAI 开发的一种高级自然语言处理模型&#xff0…

【全开源】keep健身小程序FastAdmin+ThinkPHP+UniApp

基于FastAdminUniApp&#xff08;目前仅支持微信小程序&#xff09;开发的健身相关行业小程序&#xff0c;程序适用于健身房、瑜伽馆、游泳馆、篮球馆等健身培训场所。平台拥有课程售卖、课*程*预*约、多门店管理、私教预约、教练端、会*员*卡办理、在线*商*城、分*销*模块、页…

每日一练 2024.5.16(补2024.5.12)

题目&#xff1a; 给你 n 个项目&#xff0c;编号从 0 到 n - 1 。同时给你一个整数数组 milestones &#xff0c;其中每个 milestones[i] 表示第 i 个项目中的阶段任务数量。 你可以按下面两个规则参与项目中的工作&#xff1a; 每周&#xff0c;你将会完成 某一个 项目中的…

堆的概念及结构

目录 堆的性质&#xff1a; 堆的实现 堆向下调整算法 堆的创建 堆的插入 堆的删除 堆的应用 堆排序 对比冒泡的优势&#xff1a; 代码 头文件 源文件 如果有一个关键码的集合K { &#xff0c; &#xff0c; &#xff0c;…&#xff0c; }&#xff0c;把它的所有元…

JUnit5测试用例

1.用Test注解表示为测试方法 2.使用DisplayName定义别名 3.使用Assertions类的断言方法 使用断言&#xff0c;可以判断方法的实际执行结果和预期结果是否一致 assertEqualsassertTureassertNotNullassertAllassertThrows 下图是预期与实际不同时报错图 4.使用BeforeEach注解&…

SQL操作面试题

1、NULL和 的区别 || MySQL中为什么不用NULL作为默认值 聚合函数&#xff0c;比如SUM、AVG等会忽略NULL&#xff0c;会造成数据的一个分析误差。只能通过COUNT&#xff08;*&#xff09; NULL的话只能通过ISNULL和ISNotNULL去进行判断&#xff0c;而 可以用<,>,等等…

怎么转换视频格式到mp4?格式转换,4种简单方法

转换视频格式到MP4可以使视频在各种设备上播放更加方便&#xff0c;而MP4格式的优势在于其高质量的视频和相对较小的文件大小。怎么转换视频格式到mp4&#xff1f;在本文中&#xff0c;我们将介绍四种简单有效的方法&#xff0c;帮助您快速将视频格式转换为MP4。 无论您是初学…

花花省V6淘宝客APP社交电商自营商城聚合优惠券系统功能介绍

花花省V6淘宝客APP的社交电商自营商城聚合优惠券系统具有多种功能&#xff0c;以满足用户的不同需求。以下是其主要功能的介绍&#xff1a; 首页功能&#xff1a;首页设计包含广告位、淘口令识别、微信登录、淘宝登录等。此外&#xff0c;还有淘宝返佣、拼多多返佣、京东返佣、…