设计模式(c++)

目录

    • 开闭原则
    • 合成复用原则
  • 设计模式
    • 单例模式 (Singleton)
    • 工厂方法模式(Factory Method)
    • 适配器模式 (Adapter)
    • 外观模式 (Facade)
    • 代理模式(Proxy)
    • 桥接模式(Bridge)
    • 装饰器模式(包装模式)(Decorator)
    • 模版方法模式(Template Method)
    • 策略模式(Strategy)
    • 观察者模式(Observer)
    • 责任链模式(Chain of Responsibility)

开闭原则

开闭原则(Open/Closed Principle)指出软件实体(类、模块、函数等)应该对扩展开放,但对修改关闭

合成复用原则

组合大于继承

设计模式

设计模式通常分为三种主要类型:创建型设计模式、结构型设计模式和行为型设计模式

  1. 常见的创建型设计模式包括:

    1. 单例模式(Singleton):确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。
      用于控制资源的访问,如数据库连接或文件系统。

    2. 工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。常用于将对象创建的逻辑从应用逻辑中分离出来。

    3. 抽象工厂模式(Abstract Factory):提供一个接口,用于创建相关的或依赖对象的家族,而不需要明确指定具体类。适用于系统需要处理多系列产品,但希望客户端无需关心具体实现的情况。

    4. 建造者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。通常用于创建复杂对象,允许用户按步骤指定复杂对象的各个部分,在用户代码中隔离复杂对象的创建和组装过程。

    5. 原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
      适用于创建重复对象时,效率更高的场景。

  2. 常见的结构型设计模式包括:

    1. 适配器模式(Adapter):允许将一个类的接口转换成客户期望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
    2. 装饰器模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
    3. 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。
    4. 桥接模式(Bridge):将抽象部分与实现部分分离,使它们都可以独立地变化。
    5. 外观模式(Facade):为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
    6. 组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构,组合使得用户对单个对象和组合对象的使用具有一致性。
  3. 常见的行为型设计模式包括:

    1. 策略模式(Strategy):允许在运行时选择算法的行为。
    2. 观察者模式(Observer):当一个对象状态改变时,所有依赖于它的对象都会得到通知并被自动更新。
    3. 命令模式(Command):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
    4. 责任链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
    5. 状态模式(State):允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
    6. 模板方法模式(Template Method):在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中实现。

单例模式 (Singleton)

https://zhuanlan.zhihu.com/p/37469260

  • 保证一个类仅有一个实例,并提供一个访问它的全局访问点
  • 相比于全局变量,单例模式可以延迟初始化,在使用前不会被创建,全局变量通常在启动时立即初始化

用法示例:

  • 定义一个单例类 私有化它的构造函数
  • 使用类的私有静态指针变量指向类的唯一实例;
  • 使用一个公有的静态方法获取该实例。

懒汉版(Lazy Singleton)代码示例

// 单例实例在第一次被使用时才进行初始化
class Singleton
{
private:static Singleton* instance;
private:Singleton() {};~Singleton() {};Singleton(const Singleton&);Singleton& operator=(const Singleton&);
public:static Singleton* getInstance() {if(instance == NULL) instance = new Singleton();return instance;}
};// init static member
Singleton* Singleton::instance = NULL;

Meyers’ Singleton 代码示例

// C++0x之后该实现是线程安全的
class Singleton
{
private:Singleton() { };~Singleton() { };Singleton(const Singleton&);Singleton& operator=(const Singleton&);
public:static Singleton& getInstance() {static Singleton instance;return instance;}
};

饿汉版(Eager Singleton)代码示例

// 单例实例在程序运行时被立即执行初始化
class Singleton
{
private:static Singleton instance;
private:Singleton();~Singleton();Singleton(const Singleton&);Singleton& operator=(const Singleton&);
public:static Singleton& getInstance() {return instance;}
}// initialize defaultly
Singleton Singleton::instance;

工厂方法模式(Factory Method)

  • 封装创建逻辑(解耦、可重用、一致性和可维护性)
  • 返回一个抽象类型的指针或接口,从而使得客户代码可以无需知道具体的产品类,只依赖于产品的接口或基类(多态)
  • 相比于简单工厂模式(一个工厂方法,根据接受的参数不同,而创建不同的产品实例),工厂方法模式符合开闭原则,即无需修改原有的工厂类和方法,只需增加新的产品类和对应的工厂类,(灵活性、可扩展性)

用法示例

  • 定义抽象产品类Product
  • 定义A产品类ProductA 继承自Product
  • 定义B产品类ProductB 继承自Product
  • 定义抽象工厂类Creator
  • 定义A产品工厂类CreatorA
  • 定义B产品工厂类CreatorB
  • 创建X产品工厂类的实例 用于生成相应产品类的实例(均返回抽象类型Product的指针)

代码示例

#include <iostream>
#include <memory>class Product {
public:virtual void operation() = 0;
};class ConcreteProductA : public Product {
public:void operation() override {std::cout << "Operation of ConcreteProductA" << std::endl;}
};class ConcreteProductB : public Product {
public:void operation() override {std::cout << "Operation of ConcreteProductB" << std::endl;}
};class Creator {
public:virtual Product* factoryMethod() = 0;
};class ConcreteCreatorA : public Creator {
public:Product* factoryMethod() override {return new ConcreteProductA();}
};class ConcreteCreatorB : public Creator {
public:Product* factoryFactyoryMethod() override {return new ConcreteProductB();}
};// 使用示例
int main() {std::unique_ptr<Creator> creatorA(new ConcreteCreatorA());std::unique_ptr<Product> productA(creatorA->factoryMethod());productA->operation();std::unique_ptr<Creator> creatorB(new ConcreteCreatorB());std::unique_ptr<Product> productB(creatorB->factoryMethod());productB->operation();Creator* creater = new ConcreteCreatorX();	Product* product = creater->factoryMethod();	// 多态product->operation();							// 多态return 0;
}

适配器模式 (Adapter)

  • 将不兼容的对象包装起来使其能够与其他类协同工作
  • 将一个类的接口转换成另一个期望的接口
  • 分为类适配器和对象适配器
    • 类适配器使用继承(特别是多重继承)来实现适配:
      • 优点:可以重写部分被适配者(Adaptee)的行为。
      • 缺点:因为继承了被适配者,所以耦合度较高。
    • 对象适配器使用组合来实现适配
      • 优点:更加灵活,减少了类之间的耦合度。
      • 缺点:需要额外的指针来访问被适配者。

用法示例

  • 类适配器:公有继承新接口(虚基类),私有继承旧接口,重写新接口中的方法(调用旧接口方法)
  • 对象适配器:公有继承新接口,拥有一个旧接口对象的引用,重写新接口中的方法(调用旧接口对象的成员方法)

代码示例

class OldRectangle {
public:void draw() {std::cout << "Old Rectangle draw method." << std::endl;}
};class NewShape {
public:virtual void display() = 0;virtual ~NewShape() {}
};// 类适配器
class RectangleAdapter : public NewShape, private OldRectangle {
public:void display() override {// 调用 OldRectangle 的 draw 方法draw();}
};// 对象适配器
class RectangleAdapter : public NewShape {
private:OldRectangle* oldRectangle;  // 持有一个对旧接口类的引用public:RectangleAdapter(OldRectangle* rectangle) : oldRectangle(rectangle) {}void display() override {// 调用 OldRectangle 的 draw 方法oldRectangle->draw();}~RectangleAdapter() {delete oldRectangle;}
};int main() {OldRectangle* oldRectangle = new OldRectangle();NewShape* rectangleAdapter = new RectangleAdapter(oldRectangle);rectangleAdapter->display();delete rectangleAdapter;  // 注意:这将正确地释放适配器和旧的矩形对象return 0;
}

外观模式 (Facade)

  • 提供了一个统一的接口来访问子系统中的一组接口,来简化系统接口,减少用户对子系统的耦合
  • 不符合开闭原则

用法示例

  • 定义一个外观类,拥有其他类对象作为成员,其函数成员的实现为:一组对其他对象成员函数的调用

代码示例

class MultimediaSystemFacade {
private:AudioPlayer audioPlayer;VideoPlayer videoPlayer;Broadcaster broadcaster;public:void playMultimedia() {audioPlayer.playAudio();videoPlayer.playVideo();}void sendMessage(const std::string& message) {broadcaster.broadcastMessage(message);}
};

代理模式(Proxy)

  • 提供一个代替对象(代理对象)来控制对原对象的访问。通常用于延迟处理操作、控制访问、提供智能指引等功能
  • 广泛应用于网络服务、内存中的大对象管理、安全控制等多种场景中
  • 主要有三种类型:
    • 虚拟代理:在需要时才创建开销很大的对象。
    • 保护代理:控制对原始对象的访问,用于对象应有不同的访问权限时。
    • 智能引用代理:当调用对象的特定方法时,执行一些附加操作,如计数对象引用次数、记录日志等。

用法示例

  • 定义一个代理类,拥有被代理类对象作为成员,通过代理类调用被代理类的方法,从而在调用前添加额外的控制,实现延迟处理操作、控制访问、提供智能指引等

桥接模式(Bridge)

  • 提供一个桥接结构,将抽象层和实现层解耦,从而简化了复杂系统的类结构
  • 一维扩展用继承/组合,多维扩展(品牌与产品)用桥接

用法示例

  • Abstraction (抽象类):定义抽象类的接口,它包含一个指向 Implementor 类型对象的引用。
  • RefinedAbstraction (扩充抽象类):扩展 Abstraction 定义的接口。
  • Implementor (实现类接口):定义实现类的接口,这些类具体实现基本操作,但在 Abstraction 中以抽象方式提供。
  • ConcreteImplementor (具体实现类):Implementor 接口的具体实现。

例如:用于不同类型设备(如电视、无线投影仪等)的遥控器应用,每种设备都有不同的实现,但控制接口相似(开/关、调节音量等)

  • 抽象 (Abstraction)
    抽象部分由 RemoteControl 类及其扩展类 AdvancedRemoteControl 表示。这个抽象层定义了高层和通用的操作逻辑,如切换电源 (togglePower)、调节音量 (volumeUp, volumeDown) 以及静音操作 (mute)。
    • RemoteControl (基本遥控): 提供了基础的遥控功能。
    • AdvancedRemoteControl (高级遥控): 在基本遥控的基础上增加了额外的功能,例如静音。
  • 实现 (Implementor)
    实现部分由 Device 接口及其具体实现类 TV 和 Radio 表示。这个层面处理关于设备的具体操作细节,如设备的开关状态和音量控制具体是如何执行的。
    • Device (设备接口): 定义了操作设备必须实现的方法,例如 enable(), disable(), getVolume(),
      setVolume()。
    • TV (电视): 实现了Device接口,提供了电视特有的操作方式。
    • Radio (收音机): 同样实现了Device接口,按照收音机的方式执行操作。
  • 桥接连接
    RemoteControl (抽象) 持有一个到 Device (实现) 的引用。这个引用允许抽象层通过实现层提供的接口与具体的设备进行交互,而不需要关心这些设备的具体实现细节。这就是所谓的“桥接”,即抽象层和实现层之间通过组合而非继承来建立联系,从而使得两者可以独立地变化。

装饰器模式(包装模式)(Decorator)

  • 动态地给一个对象添加一些额外的职责或功能,也是继承关系的一种代替方案(合成复用原则:组合大于继承),它通过组合而非继承增加功能,从而避免了由于继承引入的静态特性

用法示例

  • 定义装饰器类,维持一个指向被装饰类对象的引用,实现被装饰类的接口,另外添加新的功能

模版方法模式(Template Method)

  • 定义了一个操作中的算法的框架,将一些步骤的实现延迟到子类,允许子类在不改变算法结构的情况下重新定义算法的某些特定步骤
  • 封装不变部分,扩展可变部分;提取公共代码,便于维护;行为由父类控制,子类实现

用法示例

  1. 定义抽象类,设置算法框架,实现固定部分,声明由子类实现的抽象操作。
  2. 定义继承自抽象类的具体类,实现抽象类中定义的抽象方法和钩子(hook)

代码示例

// 抽象类
class Beverage {
public:// 模板方法,定义算法框架void prepareRecipe() {boilWater();brew();           // 特定于子类的步骤pourInCup();addCondiments();  // 特定于子类的步骤}
protected:virtual void brew() = 0;         // 由子类实现virtual void addCondiments() = 0;// 由子类实现void boilWater() {std::cout << "Boiling water" << std::endl;}void pourInCup() {std::cout << "Pouring into cup" << std::endl;}virtual ~Beverage() {}
};// 具体类:咖啡
class Coffee : public Beverage {
protected:void brew() override {std::cout << "Dripping Coffee through filter" << std::endl;}void addCondiments() override {std::cout << "Adding Sugar and Milk" << std::endl;}
};// 具体类:茶
class Tea : public Beverage {
protected:void brew() override {std::cout << "Steeping the tea" << std::endl;}void addCondiments() override {std::cout << "Adding Lemon" << std::endl;}
};

策略模式(Strategy)

  • 定义了一组算法,他们可以以相同的接口共享。在根据不同的条件选择不同的行为时,可以使用此模式进行解耦,使代码更易于维护和扩展
  • 使算法独立于使用他们的客户而独立变化。(在有多种算法相似的情况下,避免使用if…else所带来的复杂和难以维护)。

用法示例

  1. 定义抽象策略类,提供公共接口
  2. 定义继承自抽象策略类的具体策略类,提供具体算法实现
  3. 定义上下文类,其中维护一个对策略类对象的引用,用于设定策略,执行策略

观察者模式(Observer)

  • 定义了对象之间的一对多依赖关系,当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新
  • 常用于实现分布式事件处理系统、在应用中实现跨系统的消息交换等场景

用法示例

  • Subject(主题):也称为“被观察者”,维护一份观察者列表,并提供用于增加或删除观察者的方法。
  • Observer(观察者):为那些在主题状态发生改变时需获得通知的对象定义一个更新接口。
  • ConcreteSubject(具体主题):状态变化时,向 Observer 发送通知,存储 Observer 对象关心的数据。
  • ConcreteObserver(具体观察者):实现 Observer 的更新接口以使自身状态与主题的状态相协调。

代码示例

// Observer interface
class Observer {
public:virtual void update(float price) = 0;virtual ~Observer() {}
};// Subject interface
class Subject {
public:virtual void registerObserver(Observer* observer) = 0;virtual void removeObserver(Observer* observer) = 0;virtual void notifyObservers() = 0;virtual ~Subject() {}
};class Stock : public Subject {
private:std::list<Observer*> observers;float price;
public:// Register an observervoid registerObserver(Observer* observer) override {observers.push_back(observer);}// Remove an observervoid removeObserver(Observer* observer) override {observers.remove(observer);}// Notify all registered observersvoid notifyObservers() override {for (auto& observer : observers) {observer->update(price);}}// Method to update pricevoid setPrice(float newPrice) {price = newPrice; notifyObservers();}
};class PriceDisplay : public Observer {
private:float price;
public:void update(float newPrice) override {price = newPrice; display();}void display() const {std::cout << "Current Stock Price: $" << price << std::endl;}
};int main() {Stock stock;                           // Create a Stock object which is the subject.PriceDisplay display;                  // Create an observer.stock.registerObserver(&display);      // Register the observer with the subject.stock.setPrice(150.0f);                // Change the stock price, triggers notifications.stock.setPrice(155.5f);                // Change the stock price again.stock.removeObserver(&display);        // Unregister the observer.stock.setPrice(160.0f);                // No notification this time.return 0;
}

责任链模式(Chain of Responsibility)

  • 将请求的发送者和接收者解耦
  • 多个对象都有机会处理请求,将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

用法示例

  1. 定义处理者基类,拥有一个基类对象的引用(下一个处理者),提供处理请求的接口,提供设置下一个处理者的接口。
  2. 定义派生自基类的具体处理者类,实现处理请求的接口:处理它所负责的请求,如果可以处理就处理,不能处理就将请求转发给链上的下一个对象。

代码示例

#include <iostream>
#include <string>// Handler
class Approver {
protected:Approver* successor = nullptr;
public:void setSuccessor(Approver* successor) {this->successor = successor;}virtual void processRequest(int amount) = 0;virtual ~Approver() {}
};// ConcreteHandler1
class Manager : public Approver {
public:void processRequest(int amount) override {if (amount < 1000) {std::cout << "Manager will approve $" << amount << std::endl;} else if (successor) {successor->processRequest(amount);}}
};// ConcreteHandler2
class Director : public Approver {
public:void processRequest(int amount) override {if (amount < 5000) {std::cout << "Director will approve $" << amount << std::endl;} else if (successor) {successor->processRequest(amount);}}
};// ConcreteHandler3
class CEO : public Approver {
public:void processRequest(int amount) override {if (amount < 20000) {std::cout << "CEO will approve $" << amount << std::endl;} else {std::cout << "Request $" << amount << " needs further meeting!" << std::endl;}}
};int main() {Manager manager;Director director;CEO ceo;// Set up the chainmanager.setSuccessor(&director);director.setSuccessor(&ceo);// Various requestsmanager.processRequest(500);   // Manager handles this requestmanager.processRequest(1500);  // Director handles this requestmanager.processRequest(7000);  // CEO handles this requestmanager.processRequest(50000); // Needs further meetingreturn 0;
}

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

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

相关文章

[leetcode]search-insert-position 搜索插入位置

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int searchInsert(vector<int>& nums, int target) {int left 0, right nums.size()-1;while(left <right) {int mid left (right-left)/2;if(nums[mid] target){return mid;} else if(nu…

软件测试之接口测试(Postman/Jmeter)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、什么是接口测试 通常做的接口测试指的是系统对外的接口&#xff0c;比如你需要从别的系统来…

Omni 动画核心运动包 - 为 Unity 游戏开发者带来卓越体验

Omni 动画核心运动包 前言资源包内容领取兑换码 前言 亲爱的 Unity 游戏开发者们&#xff0c;今天要向大家介绍一款令人瞩目的动画资源 - Omni 动画核心运动包。 这个运动包包含了多达 74 个 mocap 运动动画&#xff0c;每一个动画都是由专业演员通过我们先进的人工智能驱动动…

汽车电子行业知识:什么是车载智能座舱

1.什么是车载智能座舱 车载智能座舱是指搭载在汽车内部的一种智能系统&#xff0c;它集成了各种功能和技术&#xff0c;旨在提升驾驶体验、增加安全性和提供更多的便利。这种系统可以包括诸如智能驾驶辅助、信息娱乐、智能语音控制、车内环境控制、车辆健康监测等功能。通过车…

AI数据分析003:用kimi生成一个正弦波数学动画

文章目录 一、正弦波公式二、输入内容三、输出内容一、正弦波公式 ƒ(x) = a * sin(x + x0) + b 公式中: a: 决定正弦函数振动幅度的大小; x0:表示x开始比0拖后的弧度值; b:表示函数偏离X轴的距离; 对于难以理解的学生来说,可以用动画把这个公式直观的展现出来。 二…

cartographer从入门到精通(一):cartographer介绍

一、cartographer重要文档 有关cartographer的资料有2个比较重要的网站&#xff0c;我们的介绍也是基于这两个网站&#xff0c;其中会加入自己的一些理解&#xff0c;后续也有一些对代码的修改&#xff0c;来实现我们想完善的功能。 1-Cartographer 2-Cartographer ROS 第1个…

scipy optimze求解矩阵

☆ 问题描述 Trec PD&#xff0c;T是一个(81,128)的矩阵&#xff0c;rec是一个(128,1)的向量&#xff0c;PD是一个(81,1)的向量&#xff0c;现在rec和PD是一个已知的数&#xff0c;T有一个初始值&#xff0c;我想要你优化T使得等式成立 ★ 解决方案 import numpy as np from …

【蓝桥杯省赛真题46】python数字币统计 中小学青少年组蓝桥杯比赛 算法思维python编程省赛真题解析

目录 python数字币统计 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python数字币统计 第十四届蓝桥杯青少年组python比赛省赛真题 一、题目…

中国航天:星舰与猛禽发动机数据分析

文章目录 MainReference Main 马斯克坚信&#xff0c;随着星舰的全面投入运营&#xff0c;SpaceX将能够承担地球上主轨道超过99%的载荷质量。这款第三代星舰的起飞推力将跃升至10000吨以上&#xff0c;其有效载荷质量亦将高达200吨以上。 不仅如此&#xff0c;每次发射的成本控…

吊车安全监控:车载监控系统在吊装作业中的应用

在吊装作业中&#xff0c;安全始终是第一位的。然而&#xff0c;由于吊车臂长、视野受限以及操作过程中的不确定性&#xff0c;事故风险总是存在的。为了解决这些问题&#xff0c;现代吊车普遍采用了摄像头监控系统&#xff0c;通过实时传输的图像&#xff0c;为司机提供全方位…

【鸿蒙学习笔记】数据类型

官方文档&#xff1a;ArkTS语言介绍 目录标题 声明变量声明常量数据类型 缺&#xff1a;byte charNumber类型 short int long float doubleBoolean类型 booleanString类型Void类型Object类型Array类型Enum类型Union类型Aliases类型 [代码总结] 声明变量 let hi: string hel…

【逆运动学】六轴机器人运动学逆解上位机控制

六轴机器人逆运动学上位机控制 最终效果 通过开发的上位机软件&#xff0c;实现对机械臂末端的精准操控。该软件接收输入的坐标与角度参数&#xff0c;经过算法处理计算出机械臂各关节轴的目标角度。随后&#xff0c;这些角度值被转换为对应的脉冲宽度调制&#xff08;PWM&am…

编码遵循五大设计原则创建出更加健壮、可维护和可扩展的软件系统

一、单一职责原则&#xff08;SRP&#xff09; * 定义&#xff1a;一个类应该只有一个引起它变化的原因。 * 解释&#xff1a;意味着一个类应该专注于做一件事情&#xff0c;当需求发生变化时&#xff0c;只影响到一个类。这有助于降低类间的耦合&#xff0c;使得代码更易于理…

MinGW和Cygwin的区别

介绍 MinGW和Cygwin都是windows平台下用于编译c/c代码&#xff0c; Cygwin 目的为windows平台提供类Unix环境&#xff0c;让运行在类Unix环境中的程序代码可以在windows下编译成功。cygwin提供了抽象层dll&#xff0c; 可用于将部分POSIX转换为Windows API调用&#xff0c;目…

telegram mini APP或游戏开发之bot设置

无意中发现telegram上居然也能发布小程序和游戏了,感觉发现了新大陆一样,自己好玩试了下。 参考教程 要在telegram上开发一个mini App或者game,创建一个专属于你的机器人就必不可少了。 创建bot机器人 在telegram上搜索@BotFather或者点击该这里BotFather。 如下图: 进…

一款轻量级的WPF UI库---Adonis UI

Adonis UI适用于 WPF 应用程序的轻型 UI 工具包,提供经典但增强的 Windows 视觉对象 组件内容 几乎所有 WPF 控件的模板的默认样式为方便起见,可根据需要使用两种配色方案(浅色和深色),也可用于自定义样式支持在运行时更改配色方案支持其他自定义配色方案提供水印等功能的…

查看VUE中安装包依赖的版本号

查看VUE中安装包依赖的版本号 全部依赖包版本查看某个依赖的例&#xff1a;查看stompjs 应用命令npm ls stompjs 全部依赖包版本 使用npm命令 使用 npm ls 命令可以列出项目中所有已安装的依赖包及其版本。 使用 npm list --depth1 命令可以列出项目中直接依赖的包及其版本&a…

Android中使用startActivityForResult启动活动

Android中使用startActivityForResult启动活动 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在本文中&#xff0c;我们将深入探讨Android开发中使用startActi…

线程版服务器实现(pthread_server)

用到的所有方法所需要的参数可以在wrap.c文件中查询&#xff0c;wrap中找不到的直接通过man手册查询 1.首先介绍一下我自己写的包裹文件&#xff0c;里面有各种在可能要用到的方法 wrap.c: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #…

第4章 客户端-客户端案例分析

1 Redis内存陡增 1.1.现象 服务端现象&#xff1a;Redis主节点内存陡增&#xff0c;几乎用满maxmemory&#xff0c;而从节点内存并没有变化&#xff08;正常情况下主从节点内存使用量基本相同&#xff09;。 客户端现象&#xff1a;客户端产生了OOM异常&#xff0c;也就是Redis…