设计模式8-桥模式

设计模式8-Bridge 桥模式

  • 由来与目的
  • 模式定义
  • 结构
      • 桥接模式的结构
      • 结构说明
  • 代码推导
      • 1. 类和接口的定义
      • 2. 平台实现
      • 3. 业务抽象
      • 4. 使用示例
      • 总结
      • 1. 类数量过多,复杂度高
      • 2. 代码重复
      • 3. 不符合单一职责原则
      • 4. 缺乏扩展性
      • 改进后的设计
        • 1. 抽象和实现分离(桥接模式)
        • 2. 抽象类
        • 3. 使用装饰者模式添加功能
        • 4. 使用示例
      • 改进后的优点
    • 疑问
      • 1. `protected` 访问级别的意义
      • 2. `protected` 的使用场景
      • 具体分析代码中的选择
        • 1. `protected` 访问级别的好处
        • 2. 如果使用`private`
        • 3. 如果使用`public`
      • 总结
  • 要点总结

桥模式也属于单一职责模式中的一种。

由来与目的

桥模式的由来以及目的:由于某些类型的固有的实现逻辑使他们具有两个变化的维度乃至多个维度的变化。那么此时如何应对这种多维度的变化,如何利用面向对象技术?来使得类型可以轻松地沿着两个乃至多个方向进行变化,而不引入额外的复杂度呢?那么乔模式就应运而生,他的存在就是为了解决此类问题。

模式定义

将抽象部分也就是业务功能,与实现部分分离,使他们都可以独立的变化。

结构

在这里插入图片描述
桥接模式(Bridge Pattern)是一种结构型设计模式,它旨在将抽象部分与它的实现部分分离,使它们都可以独立地变化。这种模式通过提供一种抽象化的接口来隔离实现细节,从而减少实现之间的依赖性,提高系统的灵活性和可扩展性。

桥接模式的结构

桥接模式涉及以下几个主要的参与者:

  1. Abstraction(抽象类):定义了抽象的接口,维护了一个指向实现部分 Implementor 对象的引用。
  2. RefinedAbstraction(扩充抽象类):扩展抽象类的接口。
  3. Implementor(实现类接口):定义实现类的接口,不一定与抽象类的接口完全一致。通常它仅提供基本操作,而抽象类提供基于这些基本操作的高层次操作。
  4. ConcreteImplementor(具体实现类):具体实现 Implementor 接口。

结构说明

  1. Abstraction(抽象类)

    • 维护一个指向 Implementor 类型的引用。
    • 定义高层次的操作,该操作依赖于 Implementor 中的基本操作。
  2. RefinedAbstraction(扩充抽象类)

    • 继承 Abstraction
    • 实现高层次的操作逻辑。
  3. Implementor(实现类接口)

    • 定义具体实现类需要实现的基本操作接口。
  4. ConcreteImplementor(具体实现类)

    • 实现 Implementor 接口,提供具体的实现。

桥接模式通过将抽象部分与实现部分分离,允许它们独立地变化,从而提高系统的灵活性和可扩展性。这个模式特别适用于那些需要在多个维度上独立扩展的系统。通过引入桥接模式,可以有效地减少类的数量和复杂度,提高代码的可维护性。

代码推导

class Messager{
public:virtual void Login(string username, string password)=0;virtual void SendMessage(string message)=0;virtual void SendPicture(Image image)=0;virtual void PlaySound()=0;virtual void DrawShape()=0;virtual void WriteText()=0;virtual void Connect()=0;virtual ~Messager(){}
};//平台实现class PCMessagerBase : public Messager{
public:virtual void PlaySound(){//**********}virtual void DrawShape(){//**********}virtual void WriteText(){//**********}virtual void Connect(){//**********}
};class MobileMessagerBase : public Messager{
public:virtual void PlaySound(){//==========}virtual void DrawShape(){//==========}virtual void WriteText(){//==========}virtual void Connect(){//==========}
};//业务抽象class PCMessagerLite : public PCMessagerBase {
public:virtual void Login(string username, string password){PCMessagerBase::Connect();//........}virtual void SendMessage(string message){PCMessagerBase::WriteText();//........}virtual void SendPicture(Image image){PCMessagerBase::DrawShape();//........}
};class PCMessagerPerfect : public PCMessagerBase {
public:virtual void Login(string username, string password){PCMessagerBase::PlaySound();//********PCMessagerBase::Connect();//........}virtual void SendMessage(string message){PCMessagerBase::PlaySound();//********PCMessagerBase::WriteText();//........}virtual void SendPicture(Image image){PCMessagerBase::PlaySound();//********PCMessagerBase::DrawShape();//........}
};class MobileMessagerLite : public MobileMessagerBase {
public:virtual void Login(string username, string password){MobileMessagerBase::Connect();//........}virtual void SendMessage(string message){MobileMessagerBase::WriteText();//........}virtual void SendPicture(Image image){MobileMessagerBase::DrawShape();//........}
};class MobileMessagerPerfect : public MobileMessagerBase {
public:virtual void Login(string username, string password){MobileMessagerBase::PlaySound();//********MobileMessagerBase::Connect();//........}virtual void SendMessage(string message){MobileMessagerBase::PlaySound();//********MobileMessagerBase::WriteText();//........}virtual void SendPicture(Image image){MobileMessagerBase::PlaySound();//********MobileMessagerBase::DrawShape();//........}
};void Process(){//编译时装配Messager *m =new MobileMessagerPerfect();
}

这段代码实现了一个跨平台的消息传递系统,其中包含了多个层次的抽象和具体实现。它通过将平台相关的功能和业务逻辑分离来实现不同的消息传递方式。

1. 类和接口的定义

class Messager {
public:virtual void Login(string username, string password) = 0;virtual void SendMessage(string message) = 0;virtual void SendPicture(Image image) = 0;virtual void PlaySound() = 0;virtual void DrawShape() = 0;virtual void WriteText() = 0;virtual void Connect() = 0;virtual ~Messager() {}
};

Messager 是一个抽象基类,定义了登录、发送消息、发送图片以及平台相关的功能(播放声音、绘制图形、写文本、连接)。

2. 平台实现

class PCMessagerBase : public Messager {
public:virtual void PlaySound() {//**********}virtual void DrawShape() {//**********}virtual void WriteText() {//**********}virtual void Connect() {//**********}
};class MobileMessagerBase : public Messager {
public:virtual void PlaySound() {//==========}virtual void DrawShape() {//==========}virtual void WriteText() {//==========}virtual void Connect() {//==========}
};

PCMessagerBaseMobileMessagerBase 是平台相关的具体实现类,分别实现了 PC 和移动平台上的功能。这两个类分别实现了播放声音、绘制图形、写文本和连接的方法。

3. 业务抽象

class PCMessagerLite : public PCMessagerBase {
public:virtual void Login(string username, string password) {PCMessagerBase::Connect();//........}virtual void SendMessage(string message) {PCMessagerBase::WriteText();//........}virtual void SendPicture(Image image) {PCMessagerBase::DrawShape();//........}
};class PCMessagerPerfect : public PCMessagerBase {
public:virtual void Login(string username, string password) {PCMessagerBase::PlaySound();//********PCMessagerBase::Connect();//........}virtual void SendMessage(string message) {PCMessagerBase::PlaySound();//********PCMessagerBase::WriteText();//........}virtual void SendPicture(Image image) {PCMessagerBase::PlaySound();//********PCMessagerBase::DrawShape();//........}
};class MobileMessagerLite : public MobileMessagerBase {
public:virtual void Login(string username, string password) {MobileMessagerBase::Connect();//........}virtual void SendMessage(string message) {MobileMessagerBase::WriteText();//........}virtual void SendPicture(Image image) {MobileMessagerBase::DrawShape();//........}
};class MobileMessagerPerfect : public MobileMessagerBase {
public:virtual void Login(string username, string password) {MobileMessagerBase::PlaySound();//********MobileMessagerBase::Connect();//........}virtual void SendMessage(string message) {MobileMessagerBase::PlaySound();//********MobileMessagerBase::WriteText();//........}virtual void SendPicture(Image image) {MobileMessagerBase::PlaySound();//********MobileMessagerBase::DrawShape();//........}
};

这些类继承自平台实现类,并且在每个方法中调用了相应的基类方法,添加了业务逻辑。具体而言,PCMessagerLiteMobileMessagerLite 是简化版的实现,而 PCMessagerPerfectMobileMessagerPerfect 则是带有更多功能(如播放声音)的完整实现。

4. 使用示例

void Process() {//编译时装配Messager *m = new MobileMessagerPerfect();
}

Process 函数展示了如何创建一个 MobileMessagerPerfect 实例并赋值给 Messager 指针。

总结

这段代码通过将不同平台的实现和业务逻辑分开,展示了如何使用继承和多态来实现跨平台的消息传递系统。它遵循了开闭原则(对扩展开放,对修改关闭),使得添加新的平台或功能变得更容易。具体地,Messager 定义了接口,PCMessagerBaseMobileMessagerBase 实现了平台相关的功能,而 PCMessagerLitePCMessagerPerfectMobileMessagerLiteMobileMessagerPerfect 实现了具体的业务逻辑。

这段代码虽然展示了一个灵活的跨平台消息传递系统的设计,但仍然存在一些缺陷和改进空间。以下是一些主要的缺陷及其解决方案:

1. 类数量过多,复杂度高

缺陷:每添加一个新功能或新平台,都需要创建大量新的类,导致类数量爆炸,假设此时平台类数量为n ,平台实现功能类数量为m ,那么此时类的数量为1+n+m*n,增加了代码的复杂性和维护成本。
解决方案:可以使用桥接模式(Bridge Pattern),将抽象和实现分离,从而减少类的数量和复杂度。

2. 代码重复

缺陷:许多方法在不同类中有重复的实现,如 PlaySound()DrawShape()WriteText()Connect() 方法在不同类中基本相同。
解决方案:将这些方法提取到一个单独的类中,或者使用组合而不是继承来减少代码重复。

3. 不符合单一职责原则

缺陷Messager 类同时处理平台相关的实现和业务逻辑,违背了单一职责原则,使得类的职责不清晰。
解决方案:将平台相关的实现和业务逻辑分离,使用桥接模式或策略模式将这些职责分开。

4. 缺乏扩展性

缺陷:添加新功能(如加密、压缩等)需要创建大量新的类,缺乏灵活性。
解决方案:可以使用装饰者模式(Decorator Pattern)来动态地为对象添加职责,而不需要创建大量的子类。

改进后的设计

使用桥接模式和装饰者模式重新设计:

1. 抽象和实现分离(桥接模式)
class MessagerImp {
public:virtual void PlaySound() = 0;virtual void DrawShape() = 0;virtual void WriteText() = 0;virtual void Connect() = 0;virtual ~MessagerImp() {}
};class PCMessagerImp : public MessagerImp {
public:void PlaySound() override {// PC平台实现}void DrawShape() override {// PC平台实现}void WriteText() override {// PC平台实现}void Connect() override {// PC平台实现}
};class MobileMessagerImp : public MessagerImp {
public:void PlaySound() override {// 移动平台实现}void DrawShape() override {// 移动平台实现}void WriteText() override {// 移动平台实现}void Connect() override {// 移动平台实现}
};
2. 抽象类
class Messager {
protected:MessagerImp* imp;
public:Messager(MessagerImp* imp) : imp(imp) {}virtual void Login(string username, string password) = 0;virtual void SendMessage(string message) = 0;virtual void SendPicture(Image image) = 0;virtual ~Messager() {}
};class MessagerLite : public Messager {
public:MessagerLite(MessagerImp* imp) : Messager(imp) {}void Login(string username, string password) override {imp->Connect();// Lite版特有的登录逻辑}void SendMessage(string message) override {imp->WriteText();// Lite版特有的发送消息逻辑}void SendPicture(Image image) override {imp->DrawShape();// Lite版特有的发送图片逻辑}
};class MessagerPerfect : public Messager {
public:MessagerPerfect(MessagerImp* imp) : Messager(imp) {}void Login(string username, string password) override {imp->PlaySound();imp->Connect();// Perfect版特有的登录逻辑}void SendMessage(string message) override {imp->PlaySound();imp->WriteText();// Perfect版特有的发送消息逻辑}void SendPicture(Image image) override {imp->PlaySound();imp->DrawShape();// Perfect版特有的发送图片逻辑}
};
3. 使用装饰者模式添加功能
class MessagerDecorator : public Messager {
protected:Messager* messager;
public:MessagerDecorator(Messager* messager) : Messager(messager->imp), messager(messager) {}void Login(string username, string password) override {messager->Login(username, password);}void SendMessage(string message) override {messager->SendMessage(message);}void SendPicture(Image image) override {messager->SendPicture(image);}
};class EncryptedMessager : public MessagerDecorator {
public:EncryptedMessager(Messager* messager) : MessagerDecorator(messager) {}void Login(string username, string password) override {// 加密登录MessagerDecorator::Login(username, password);}void SendMessage(string message) override {// 加密消息MessagerDecorator::SendMessage(message);}void SendPicture(Image image) override {// 加密图片MessagerDecorator::SendPicture(image);}
};
4. 使用示例
void Process() {MessagerImp* pcImp = new PCMessagerImp();Messager* m = new EncryptedMessager(new MessagerPerfect(pcImp));m->Login("user", "password");m->SendMessage("Hello, World!");// Clean updelete m;delete pcImp;
}

改进后的优点

  1. 减少类数量:通过桥接模式,将平台相关实现和业务逻辑分离,减少了类的数量,此时类的数量为(1+n+m) < (1+n+m*n)。
  2. 减少代码重复:将公共方法提取到实现类中,减少了代码重复。
  3. 职责清晰:将平台相关实现和业务逻辑分离,符合单一职责原则。
  4. 增加扩展性:通过装饰者模式,能够动态地添加新功能,而无需创建大量新的子类。

通过这些改进,可以显著提高代码的可维护性、可扩展性和清晰性。

疑问

在面向对象编程中,选择成员变量的访问级别时,需要考虑类的设计和使用场景。在这段代码中,Messager类的imp成员变量被声明为protected,而不是private或者public,这是有特定原因的。

1. protected 访问级别的意义

protected 访问级别允许子类访问和修改基类中的成员变量,同时对类外部保持不可见。这样可以在保证类的封装性的同时,允许子类进行适当的扩展和修改。

2. protected 的使用场景

在这段代码中,Messager类的设计是为了作为一个基类,它的主要作用是定义接口和提供基础的实现,而具体的实现细节由其子类来完成。因此,将imp成员变量设为protected可以让子类方便地访问和操作这个变量,而无需通过公共接口来访问。

具体分析代码中的选择

1. protected 访问级别的好处
class Messager {
protected:MessagerImp* imp;
public:Messager(MessagerImp* imp) : imp(imp) {}virtual void Login(string username, string password) = 0;virtual void SendMessage(string message) = 0;virtual void SendPicture(Image image) = 0;virtual ~Messager() {}
};class MessagerLite : public Messager {
public:MessagerLite(MessagerImp* imp) : Messager(imp) {}void Login(string username, string password) override {imp->Connect();// Lite版特有的登录逻辑}void SendMessage(string message) override {imp->WriteText();// Lite版特有的发送消息逻辑}void SendPicture(Image image) override {imp->DrawShape();// Lite版特有的发送图片逻辑}
};

在这种设计下,MessagerLite和其他子类可以直接访问imp,这使得子类可以轻松地调用平台相关的实现方法,如Connect()WriteText()DrawShape()

2. 如果使用private

如果将imp设为private,子类将无法直接访问imp,需要通过公共的getter和setter方法。这增加了额外的复杂性,而且在某些情况下可能会影响性能和代码的可读性。

class Messager {
private:MessagerImp* imp;
public:Messager(MessagerImp* imp) : imp(imp) {}MessagerImp* getImp() { return imp; }virtual void Login(string username, string password) = 0;virtual void SendMessage(string message) = 0;virtual void SendPicture(Image image) = 0;virtual ~Messager() {}
};class MessagerLite : public Messager {
public:MessagerLite(MessagerImp* imp) : Messager(imp) {}void Login(string username, string password) override {getImp()->Connect();// Lite版特有的登录逻辑}void SendMessage(string message) override {getImp()->WriteText();// Lite版特有的发送消息逻辑}void SendPicture(Image image) override {getImp()->DrawShape();// Lite版特有的发送图片逻辑}
};
3. 如果使用public

如果将imp设为public,则任何外部代码都可以直接访问和修改imp,这违反了封装原则,容易导致错误和不必要的依赖。

class Messager {
public:MessagerImp* imp;Messager(MessagerImp* imp) : imp(imp) {}virtual void Login(string username, string password) = 0;virtual void SendMessage(string message) = 0;virtual void SendPicture(Image image) = 0;virtual ~Messager() {}
};// 外部代码可以直接访问 imp
Messager* m = new MessagerLite(new PCMessagerImp());
m->imp->Connect(); // 不推荐

总结

MessagerImp* imp设为protected是为了在保持封装性的同时,让子类能够方便地访问和使用该成员变量。这种设计既保证了基类和子类之间的良好协作,又避免了将实现细节暴露给类的外部,提高了代码的可维护性和扩展性。

要点总结

  • 模式使用对象间的组合关系解耦合了。抽象和现实之间固有的绑定关系,使得抽象可实现可以沿着各自的维度来变化所,所谓抽象和实现沿着各自维度的变化,即子类化他们
  • 强模式有时候类似于多继承方案。但是多继承方案往往违背单一职责,原则即一个类只有一个变化的原因,复用性比较差。桥模式是比多继承方案更好的解决方法。
  • 乔模桥模式的应用一般在两个非常强的变化维度,有时一个内页。有。多于两个的变化维度,这时可以使用桥的扩展模式。

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

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

相关文章

【云岚到家】-day05-6-项目迁移-门户-CMS

【云岚到家】-day05-6-项目迁移-门户-CMS 4 项目迁移-门户4.1 迁移目标4.2 能力基础4.2.1 缓存方案设计与应用能力4.2.2 静态化技术应用能力 4.3 需求分析4.3.1 界面原型 4.4 系统设计4.4.1 表设计4.4.2 接口与方案4.4.2.1 首页信息查询接口4.4.3.1 数据缓存方案4.4.3.2 页面静…

linux的学习(四):磁盘,进程,定时,软件包的相关命令

简介 关于磁盘管理&#xff0c;进程管理&#xff0c;定时任务&#xff0c;软件包管理的命令的使用 磁盘管理类命令 du du 目录名&#xff1a; 查看文件和目录占用的磁盘空间 参数&#xff1a; -h&#xff1a;可以看到大小的单位&#xff0c;g,mb-a&#xff1a;还可以看到文…

红色文化3D虚拟数字展馆搭建意义深远

在房地产与土地市场的浪潮中&#xff0c;无论是新城规划、乡村振兴&#xff0c;还是商圈建设&#xff0c;借助VR全景制作、虚拟现实和web3d开发技术打造的全链条无缝VR看房新体验。不仅极大提升了带看与成交的转化率&#xff0c;更让购房者足不出户&#xff0c;即可享受身临其境…

毕设项目springboot+vue实现的在线求职平台

一、前言 随着信息技术的飞速发展和互联网的普及&#xff0c;线上求职已成为众多求职者和企业招聘的重要渠道。为满足市场需求&#xff0c;我们利用Spring Boot和Vue技术栈&#xff0c;开发了一款功能全面、用户友好的在线求职平台。本文将对该平台的设计、实现及关键技术进行详…

Python与自动化脚本编写

Python与自动化脚本编写 Python因其简洁的语法和强大的库支持&#xff0c;成为了自动化脚本编写的首选语言之一。在这篇文章中&#xff0c;我们将探索如何使用Python来编写自动化脚本&#xff0c;以简化日常任务。 一、Python自动化脚本的基础 1. Python在自动化中的优势 Pyth…

昇思25天学习打卡营第15天|基于MobileNetv2的垃圾分类

一、关于MobileNetv2 MobileNet网络专注于移动端、嵌入式或IoT设备的轻量级CNN网络。MobileNet网络使用深度可分离卷积&#xff08;Depthwise Separable Convolution&#xff09;的思想在准确率小幅度降低的前提下&#xff0c;大大减小了模型参数与运算量。并引入宽度系数 α和…

LLM 构建Data Multi-Agents 赋能数据分析平台的实践之④:数据分析之三(数据展示)

概述 在先前探讨的文章中&#xff0c;我们构建了一个全面的数据测试体系&#xff0c;该体系遵循“数据获取—数据治理—数据分析”的流程。如何高效地构建数据可视化看板&#xff0c;以直观展现分析结果&#xff0c;正逐渐成为利用新兴技术提升效能的关键领域。伴随业务拓展、数…

SQl server 日期函数查询相关练习

练习1.按月份分析销售数据。 create database date_db; use date_db; CREATE TABLE SalesData ( SaleID INT PRIMARY KEY IDENTITY(1,1), ProductName NVARCHAR(100) NOT NULL, SaleAmount DECIMAL(10, 2) NOT NULL, SaleDate DATE NOT NULL ); INSERT INTO Sa…

华为USG6000V防火墙v1

目录 一、实验拓扑图 二、要求 三、IP地址规划 四、实验配置 1&#x1f923;防火墙FW1web服务配置 2.网络配置 要求1&#xff1a;DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 要求2&#xff1a;生产区不…

使用Python和MediaPipe实现手势控制音量(Win/Mac)

1. 依赖库介绍 OpenCV OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它包含了数百个计算机视觉算法。 MediaPipe MediaPipe是一个跨平台的机器学习解决方案库&#xff0c;可以用于实时人类姿势估计、手势识…

Flask 用 Redis 缓存键值对-实例

Flask 使用起 Redis 来简直就是手到擒来&#xff0c;比 MySQL 简单多了&#xff0c;不需要那么多配置&#xff0c;实际代码就这么多&#xff0c;直接复制就能用。除了提供简单实用的实例以外&#xff0c;本文后面还会简单介绍一下 Redis 的安装与使用&#xff0c;初学者也能一看…

Nginx部署Vite打包的带前缀的项目

之前有篇文章&#xff0c;需要参考一下&#xff1a;https://zhangdapeng.blog.csdn.net/article/details/140388105 在这篇文章的基础之上&#xff0c;我测试了Vite打包的项目。 首先&#xff0c;我在vite配置文件里面添加了前缀&#xff1a; import {defineConfig} from v…

生物素-十一聚乙二醇-沙利度胺;Biotin-PEG11-Thalidomide

Biotin-PEG11-Thalidomide&#xff0c;即生物素-十一聚乙二醇-沙利度胺&#xff0c;是一种结合了生物素、十一聚乙二醇&#xff08;PEG11&#xff09;和沙利度胺的复杂化合物。以下是对该化合物的详细分析&#xff1a; 一、组成成分及特性 生物素&#xff08;Biotin&#xff09…

访问 Postman OAuth 2.0 授权的最佳实践

OAuth 2.0 代表了 web 安全协议的发展&#xff0c;便于在多个平台上进行授权服务&#xff0c;同时避免暴露用户凭据。它提供了一种安全的方式&#xff0c;让用户可以授权应用程序访问服务。 在 Postman 中开始使用 OAuth 2.0 Postman 是一个流行的API客户端&#xff0c;支持 …

2024-07-14 Unity插件 Odin Inspector1 —— 插件介绍

文章目录 1 介绍2 模块3 学习目的 1 介绍 ​ Odin Inspector 是 Unity 的一个插件&#xff0c;拥有强大、自定义和用户友好的编辑器&#xff0c;而无需编写任何自定义编辑器代码&#xff0c;使得编程过程中的数据可视化更容易实现。 ​ 具体功能包括&#xff1a; 更舒适美观…

2024-07-12 Unity AI状态机1 —— 框架介绍

文章目录 1 有限状态机2 状态机实现框架2.1 StateMachine2.2 BaseState2.3 ...State2.4 IAIObject 3 框架类图 本文章参考 B 站唐老狮 2023 年直播内容。点击前往唐老狮 B 站主页。 1 有限状态机 ​ 有限状态机&#xff08;Finite - State Machine&#xff0c;FSM&#xff09…

Docker安装RabbitMQ(带web管理端)

1.拉取带web管理的镜像 可以拉取rabbitmq对应版本的web管理端&#xff0c;比如&#xff1a;rabbitmq:3.9.11-management&#xff0c;也可以直接拉取带web管理端的最新版本 rabbitmq:management. docker pull rabbitmq:3.9.11-management 注意&#xff1a;如果docker pull ra…

websockt初始化,创建一个webSocket示例

写文思路&#xff1a; 以下主要从几个方面着手写websocket相关&#xff0c;包括以下&#xff1a;什么是webSocket&#xff0c;webSocket的优点和劣势&#xff0c;webSocket工作原理&#xff0c;webSocket握手示例&#xff0c;如何使用webSocket(使用webSocket的一个示例)&#…

Chapter 1:数据结构前言

在数字化的世界里&#xff0c;我们每天都在与数据打交道。然而&#xff0c;你是否曾想过&#xff0c;这些数据是如何被组织、存储和处理的&#xff1f;这就是数据结构的魅力所在。 数据结构&#xff0c;简单来说&#xff0c;就是数据的组织方式。它决定了我们如何高效地访问和操…

object-C 解答算法:合并两个有序数组(leetCode-88)

合并两个有序数组(leetCode-88) 题目如下图:(也可以到leetCode上看完整题目,题号88) 首先搞懂,什么叫“非递减顺序” 非递减顺序,是指一个序列中的元素从前往后&#xff08;或从左到右&#xff09;保持不减少或相等。 这意味着序列中的元素可以保持相同的值&#xff0c;但不会…