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

适配器模式与桥接模式-灵活应对变化的两种设计策略大比拼

在这里插入图片描述​🌈 个人主页:danci_
🔥 系列专栏:《设计模式》
💪🏻 制定明确可量化的目标,坚持默默的做事。
🚀 转载自:设计模式深度解析:适配器模式与桥接模式-灵活应对变化的两种设计策略大比拼


适配器模式与桥接模式-灵活应对变化的两种设计策略大比拼

探索设计模式的魅力:深入了解适配器模式-优雅地解决接口不匹配问题文章浏览阅读9k次,点赞115次,收藏91次。适配器模式是一种常用的设计模式,它通过将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接口不兼容或不匹配而无法协同工作的类能够一起工作。适配器模式主要应用于解决不同组件之间的接口不兼容问题,或者在第三方库与现有系统之间进行集成。通过使用适配器模式,可以提高代码的灵活性和复用性,降低系统间的耦合度。适配器模式有多种实现方式,包括类适配器模式、对象适配器模式和接口适配器模式。在使用适配器模式时,需要注意其优缺点,并根据实际需求选择合适的实现方式。适配器模式可以与其他设计模式结合使用,如与装饰器模…https://blog.csdn.net/danci_/article/details/135891805

探索设计模式的魅力:精准解读桥接模式-用桥接模式构建可扩展的软件系统文章浏览阅读4.8k次,点赞74次,收藏103次。桥接模式是一种设计模式,旨在将抽象和实现部分分离,使它们可以独立地变化。这种模式的目的是提高系统的灵活性和可扩展性。桥接模式的主要思想是将抽象和实现通过一个桥接类连接起来,从而实现它们的解耦。在这种模式中,抽象部分可以根据需要进行扩展,而实现部分可以自由地变化,而不影响彼此。桥接模式在处理多个独立变化的维度、解耦继承关系、处理平台差异和扩展现有系统等方面具有广泛的应用领域。通过使用桥接模式,可以提高系统的可维护性和可扩展性,使系统更加灵活和适应变化。通过桥接模式,将系统中的抽象部分与实现部分解耦,从而…https://blog.csdn.net/danci_/article/details/135949676

引言:
    在本篇文章中,我们将通过生动的说明和直观的比较,带您深入了解适配器模式和桥接模式,助您在软件设计的海洋中乘风破浪。 🚢

文章目录

  • 🎉 <font size=''>探索设计模式的奥秘 🚀</font >
  • Part 1: 适配器模式:让不兼容的接口找到共同语言 💡
    •  定义
    •  作用</code>
  • Part 2: 桥接模式:分离抽象和实现,让它们可以独立变化 🌉
    •  定义
    •  用途
  • Part 3: 大比拼:适配器模式 vs 桥接模式 🤼
    • 结构图 💖
      • 适配器模式(`图1`)
      • 桥接模式(`图2`)
      • 结构上的不同 🛠️
    • 使用场景 🚀
    • 优缺点 🎭
  • <code>Part 4: 易混场景💔<code>
    • 场景:图形渲染系统
    • 使用适配器模式实现:让不兼容的接口找到共同语言 🤔
    • 使用桥接模式:分离抽象和实现,让它们可以独立变化 😉
    • 决择 😅
  • 🔥 结论与行动呼吁 💖

🎉 探索设计模式的奥秘 🚀

  
在这里插入图片描述
  
    设计模式作为软件工程中的黄金准则,引领着开发者高效地解决一般问题,优化代码结构。在这次的探索旅途中,我们深入两个灵活应对变化的英雄——适配器模式和桥接模式。让我们一起解锁它们如何在日益复杂的软件开发世界中,提供优雅的解决方案吧!🎯

    在探索软件工程的广漫领域中,设计模式以其构建高效、可维护代码的能力而矗立不倒。这些模式不仅是编程世界的灵魂,而且是连接理论与实践的桥梁。随着技术的不断进步,设计模式提供了一种以经验为基础的解决方案,使开发者能够避免重新发明轮子。在本章节中,我们将深入探索设计模式的奥秘,揭示它们的本质、如何在各种项目中有效应用它们,以及它们如何帮助我们在日渐复杂的软件开发任务中航行。通过探索经典模式如单例、工厂、策略和观察者模式,我们将展开有关如何通过重用设计模式来优化代码结构、提高代码的复用率以及增强软件的灵活性和可扩展性的讨论。加入我们的旅程,让我们一起探索设计模式的世界,解锁编程的高级技巧,有效应对日益增长的软件复杂性。🌈
 

Part 1: 适配器模式:让不兼容的接口找到共同语言 💡

  
在这里插入图片描述

  

 定义

✨ 适配器模式是一种结构型设计模式,它允许将一个类的接口转换为客户端所期望的另一个接口,从而帮助原本因接口不兼容而无法协同工作的类实现合作。

    适配器模式如同生活中的变压器,其主要作用是将一个类的接口转换成客户期望的另一个接口,使原本因接口不兼容而不能一起工作的那些类可以一起工作。这个部分,我们将通过实际案例,揭示适配器模式的魅力。
  

 作用

    在实际编程中,适配器模式的主要作用是解决接口之间的不兼容性问题。当系统中存在已经实现的类,但其接口与客户端所期望的接口不一致时,通过适配器模式,我们可以在不修改现有类的情况下,将它们的接口转换为客户端期望的接口。这不仅避免了大量代码的修改,还提高了系统的灵活性和可扩展性。

    简而言之,适配器模式就像是一个转换器或翻译器,使得原本无法直接交流的类能够顺畅地协同工作。
  

Part 2: 桥接模式:分离抽象和实现,让它们可以独立变化 🌉

  
在这里插入图片描述
  
    桥接模式通过将抽象化与实现化解耦,使得二者可以独立变化,进而在实际的软件开发过程中,实现细节可以更灵活地应对变化。本章节将探讨桥接模式的定义、用途,以及如何在设计时利用它达到设计上的高度自由。
  

 定义

✨ 桥接模式是一种将抽象部分与实现部分分离,以便它们可以独立变化的结构型设计模式,使得两者都能进行扩展。
 

 用途

    桥接模式是一种结构型设计模式,它的主要作用是将抽象部分与实现部分分离,使得它们可以独立地变化。这种分离方式有助于增加系统的灵活性和可扩展性。

    桥接模式的用途主要体现在以下几个方面:👇

  1. 抽象与实现解耦:桥接模式通过将抽象部分与具体实现部分分离,允许它们各自独立地变化。这种解耦方式有助于减少代码之间的耦合度,使得系统更加灵活和易于维护。

  2. 支持多种实现方式:在桥接模式中,一个抽象类可以对应多个实现类。这意味着,当我们需要根据不同的需求实现不同的功能时,只需要添加新的实现类,而不需要修改原有的抽象类或代码逻辑。这大大简化了代码结构,并提高了代码的可重用性。

  3. 扩展性强:由于桥接模式允许抽象部分和实现部分独立变化,因此当需要添加新的抽象或实现时,只需要在相应的部分进行扩展,而不需要修改整个系统的结构。这种扩展性使得桥接模式在构建大型复杂系统时特别有用。

  4. 跨平台开发:桥接模式在处理跨平台开发问题时也表现出色。通过将平台相关的代码与平台无关的代码分离,我们可以轻松地在不同的平台上实现相同的功能。这大大减少了重复代码和维护成本。

    举例来说,假设我们正在开发一个图形编辑软件,其中包含了多种图形对象(如矩形、圆形等)以及多种绘制工具(如铅笔、画笔等)。在这个场景中,我们可以使用桥接模式将图形对象与绘制工具分离。具体来说,我们可以定义一个图形对象的抽象类,并为每种图形对象提供一个实现类。同时,我们可以定义一个绘制工具的接口,并为每种绘制工具提供一个实现类。这样,当我们需要添加新的图形对象或绘制工具时,只需要添加相应的实现类,而不需要修改其他部分的代码。此外,由于桥接模式的灵活性,我们还可以轻松地在不同的平台上实现相同的图形编辑功能。

    总而言之,桥接模式通过分离抽象与实现,提高了系统的灵活性和可扩展性。在需要支持多种实现方式、进行跨平台开发或构建大型复杂系统时,桥接模式是一种非常有用的设计模式。
 

Part 3: 大比拼:适配器模式 vs 桥接模式 🤼

  
在这里插入图片描述
  
    为什么选择适配器模式?在何种场景下桥接模式表现更佳?透过一系列的比较分析,本部分将深入讨论两种设计模式的结构图、使用场景、优缺点,以及它们在解决软件设计问题时的不同效果。
  

结构图 💖

  
在这里插入图片描述
  

适配器模式(图1

适配器模式的主要目的是将一个类的接口转换成客户期望的另一个接口,从而使得原本不兼容的类可以一起工作。它通常涉及到一个适配器类,该类持有对适配者类对象的引用,并通过实现目标接口来提供对适配者方法的访问。

主要角色:

  1. 目标(Target)接口:定义客户期望的接口。
  2. 适配者(Adaptee)类:现有的、需要被适配的类。
  3. 适配器(Adapter)类:实现目标接口并持有对适配者对象的引用,将请求转发给适配者。

    适配器模式的关键在于通过适配器类将目标接口与适配者类连接起来,使得客户可以透明地调用适配者类的方法,而无需知道其具体的实现细节。
  

桥接模式(图2

桥接模式的主要目的是将抽象部分与实现部分分离,使得它们可以独立地变化。它通常涉及到两个层次的结构:抽象层和实现层。抽象层定义了抽象接口,而实现层则提供了具体实现。两者之间通过桥接(Bridge)进行连接。

主要角色:

  1. 抽象(Abstraction)类:定义抽象接口,并持有一个对实现类对象的引用(即桥)。
  2. 实现(Implementor)接口:定义实现类的接口。
  3. 具体实现(Concrete Implementor)类:实现实现接口,提供具体的实现。

    桥接模式的关键在于将抽象与实现解耦,使得它们可以独立地变化和发展。抽象类通过持有对实现类对象的引用来动态地绑定到具体的实现上,从而实现了抽象与实现的分离。

  

结构上的不同 🛠️

 

  1. 关注点不同:适配器模式主要关注将一个接口适配成另一个接口,以解决接口不兼容的问题;而桥接模式则更关注将抽象与实现分离,以实现独立的变化和扩展。
  2. 连接方式不同:在适配器模式中,适配器类通过继承或引用适配者类来连接目标接口和适配者类;而在桥接模式中,抽象类通过持有对实现类对象的引用来连接抽象接口和实现接口。
  3. 灵活性不同:由于桥接模式将抽象与实现完全分离,因此它在处理变化时更加灵活。可以独立地增加新的抽象类或实现类,而不需要修改原有的代码。而适配器模式在处理变化时可能需要修改适配器类或适配者类,以适应新的接口需求。
  4. 设计复杂度不同:桥接模式的设计相对复杂,需要正确地识别出系统中两个独立变化的维度,并设计相应的抽象类和实现类。而适配器模式的设计相对简单,只需要定义一个适配器类来连接目标接口和适配者类即可。

    适配器模式和桥接模式在结构上存在一些明显的不同。适配器模式更注重接口的适配和兼容性,而桥接模式更注重抽象与实现的分离和灵活性。在实际应用中,应根据具体的需求和场景选择合适的设计模式。

  

使用场景 🚀

  
在这里插入图片描述
  

优缺点 🎭

  
在这里插入图片描述
  
    综上所述,适配器模式和桥接模式都是常用的设计模式,它们各自有适用的场景和优缺点。在选择使用哪种模式时,需要根据具体的软件设计问题和需求来进行权衡和决策。如果需要解决两个已有接口之间的匹配问题,可以考虑使用适配器模式;如果需要在抽象和实现之间增加灵活性,特别是当抽象和实现都需要独立变化时,可以考虑使用桥接模式。
  

Part 4: 易混场景💔

  

场景:图形渲染系统

✨ 假设我们正在开发一个图形渲染系统,该系统需要支持多种不同类型的图形(如圆形、矩形、自定义图形等)和多种渲染方式(如软件渲染、硬件加速渲染等)。这个系统应该能够灵活地添加新的图形类型和渲染方式,而不需要修改现有的代码。
  

使用适配器模式实现:让不兼容的接口找到共同语言 🤔

  
    在这个场景中,我们可以将每种图形类型看作是一个适配者(Adaptee),而将渲染方式看作是客户端期望的接口(Target)。适配器(Adapter)则负责将图形类型的接口适配到渲染方式所需的接口上。
  

  实现

  1. 定义渲染接口(Target):首先,我们定义一个渲染接口,它包含了渲染图形所需的方法。
  2. 实现图形类(Adaptee):然后,我们为每种图形类型实现一个类,这些类具有各自特有的属性和方法。
  3. 创建适配器类(Adapter):接下来,我们为每种图形类型创建一个适配器类。适配器类实现了渲染接口,并持有对相应图形类对象的引用。适配器类中的方法会将渲染请求转发给图形类对象,并在必要时进行接口转换。
  4. 客户端调用:客户端代码通过渲染接口调用适配器类的方法,从而实现对不同图形类型的渲染。

  优点

  1. 灵活性:适配器模式允许将不兼容的接口进行适配,使得原本无法协同工作的类能够一起工作。这提供了很大的灵活性,特别是在面对不断变化的渲染方式时。
  2. 复用性:现有的图形类可以被复用,而不需要进行大量修改。适配器类负责处理接口之间的转换,使得原有的图形类可以继续发挥作用。
  3. 透明性:对于客户端来说,使用适配器模式可以使得接口转换变得透明。客户端只需要调用适配器提供的接口,而不需要关心具体的实现细节。

  缺点

  1. 设计复杂度:适配器模式可能会增加系统的设计复杂度。需要仔细考虑如何设计适配器类,以确保它能够正确地转换接口。
  2. 代码可读性:过度使用适配器模式可能会导致代码变得难以理解和维护。因为系统中会存在大量的适配器类,它们之间的关系可能会变得非常复杂。
  3. 性能开销:适配器模式可能会引入额外的性能开销。因为接口转换需要额外的计算和处理,特别是在处理大量图形渲染请求时,这可能会成为性能瓶颈。
      

    Java实现如下:(详见:深入了解适配器模式-优雅地解决接口不匹配问题

// 渲染接口  
interface Renderer {  void render();  
}  // 圆形类(Adaptee)  
class Circle {  public void draw() {  System.out.println("Drawing Circle");  }  
}  // 圆形渲染适配器(Adapter)  
class CircleRendererAdapter implements Renderer {  private Circle circle;  public CircleRendererAdapter(Circle circle) {  this.circle = circle;  }  @Override  public void render() {  circle.draw();  System.out.println("Circle has been rendered using Adapter Pattern");  }  
}  // 客户端代码  
public class AdapterPatternDemo {  public static void main(String[] args) {  Circle circle = new Circle();  Renderer renderer = new CircleRendererAdapter(circle);  renderer.render();  }  
}

  

使用桥接模式:分离抽象和实现,让它们可以独立变化 😉

    在这个场景中,我们可以将图形类型和渲染方式看作是两个独立变化的维度。抽象类(Abstraction)负责定义图形的通用接口,并持有一个对实现类(Implementor)的引用,以实现图形的渲染。

  实现

  1. 定义实现接口(Implementor):首先,我们定义一个渲染接口(实现接口),它包含了渲染图形所需的方法。
  2. 实现具体渲染类(Concrete Implementor):然后,我们为每种渲染方式实现一个类,这些类实现了渲染接口。
  3. 定义抽象图形类(Abstraction):接下来,我们定义一个抽象图形类,它包含了图形的通用属性和方法,并持有一个对渲染接口对象的引用(即桥)。抽象图形类中的方法会使用渲染接口对象来进行图形的渲染。
  4. 实现具体图形类(Refined Abstraction):然后,我们为每种图形类型实现一个具体图形类,这些类继承自抽象图形类,并提供了具体图形的实现。
    客户端调用:客户端代码通过创建具体图形类和具体渲染类的对象,并将它们组合在一起,从而实现对不同图形类型的渲染。

  优点

  1. 分离抽象和实现:桥接模式将抽象部分和实现部分完全分离,使得它们可以独立地变化和发展。这提供了更好的解耦和组合性。
  2. 扩展性:桥接模式使得系统更容易扩展。无论是增加新的图形类型还是新的渲染方式,都不需要修改现有的代码,只需要增加相应的具体类即可。
  3. 灵活性:桥接模式提供了更大的灵活性。不同的图形类型和渲染方式可以任意组合,以满足不同的需求

  缺点

  1. 设计复杂度:桥接模式的设计相对复杂。需要正确地识别出系统中两个独立变化的维度,并设计相应的抽象类和实现类。这需要对系统有深入的理解和分析。
  2. 理解难度:对于初学者来说,桥接模式可能较难理解。因为它涉及到抽象类、实现类以及它们之间的关系,需要一定的抽象思维能力才能掌握。
  3. 可能增加开发成本:由于桥接模式的设计复杂度较高,因此可能会增加系统的开发成本。需要投入更多的时间和精力来设计和实现相应的类及其关系。
      

    Java实现如下:(详见:用桥接模式构建可扩展的软件系统

// 渲染接口(Implementor)  
interface DrawingAPI {  void drawCircle(int x, int y, int radius);  
}  // 软件渲染实现  
class SoftwareDrawingAPI implements DrawingAPI {  @Override  public void drawCircle(int x, int y, int radius) {  System.out.println("Drawing circle at (" + x + "," + y + ") with radius " + radius + " using Software Rendering");  }  
}  // 硬件渲染实现  
class HardwareDrawingAPI implements DrawingAPI {  @Override  public void drawCircle(int x, int y, int radius) {  System.out.println("Drawing circle at (" + x + "," + y + ") with radius " + radius + " using Hardware Accelerated Rendering");  }  
}  // 抽象图形类(Abstraction)  
abstract class Shape {  protected DrawingAPI drawingAPI;  protected Shape(DrawingAPI drawingAPI) {  this.drawingAPI = drawingAPI;  }  public abstract void draw();  public void resize() {  System.out.println("Resizing shape");  }  
}  // 具体圆形类(Refined Abstraction)  
class CircleShape extends Shape {  private int x, y, radius;  public CircleShape(int x, int y, int radius, DrawingAPI drawingAPI) {  super(drawingAPI);  this.x = x;  this.y = y;  this.radius = radius;  }  @Override  public void draw() {  drawingAPI.drawCircle(x, y, radius);  }  
}  // 客户端代码  
public class BridgePatternDemo {  public static void main(String[] args) {  DrawingAPI softwareDrawingAPI = new SoftwareDrawingAPI();  Shape circleSoftware = new CircleShape(50, 100, 30, softwareDrawingAPI);  circleSoftware.draw();  circleSoftware.resize();  DrawingAPI hardwareDrawingAPI = new HardwareDrawingAPI();  Shape circleHardware = new CircleShape(50, 100, 30, hardwareDrawingAPI);  circleHardware.draw();  circleHardware.resize();  }  
}

  

决择 😅

  
    适配器模式和桥接模式在图形渲染系统的场景中都有各自的优缺点。选择哪种模式取决于具体的需求和设计目标。如果更注重灵活性和复用性,可以选择适配器模式;如果更注重解耦和扩展性,可以选择桥接模式。
    在场景中,适配器模式和桥接模式都可以用来实现灵活性和可扩展性。选择哪种模式取决于设计的侧重点和需求

  1. 如果我们更关注于将现有组件(图形类)适配到新的接口(渲染方式)上,并且希望在不修改现有代码的情况下增加新的渲染方式,那么适配器模式可能更合适。
  2. 如果我们更关注于将抽象(图形类)与实现(渲染方式)分离,并且希望能够独立地扩展图形类型和渲染方式,那么桥接模式可能更合适。桥接模式提供了更好的解耦和组合性,使得我们可以更灵活地组合不同的图形类型和渲染方式。
      

🔥 结论与行动呼吁 💖

  
在这里插入图片描述

  

    在软件设计的世界里,每一个模式都像是一块精心雕琢的积木,为构建稳固且灵活的软件架构提供了不可或缺的组件。当我们谈到适配器模式和桥接模式时,这两块积木尤为重要,它们能够助您游刃有余地应对软件开发中的种种挑战,引领您走向更加创新和变革的道路。👍
  

    适配器模式,顾名思义,它的作用就像是一个转换器,将原本不兼容的接口进行适配,使之能够协同工作。想象一下,在软件项目中,您可能会遇到各种已有的类或库,它们的接口并不符合当前项目的需求。这时,适配器模式就能派上用场,让您无需改动原有的代码,只需编写一个适配器类,即可将不兼容的接口转化为项目所需的接口。这种灵活性不仅降低了维护成本,还提高了代码的可重用性。🧐
  

    桥接模式,则更注重于抽象与实现的分离。它让抽象部分和实现部分独立地变化,降低了它们之间的耦合度。这意味着,当您需要增加新的抽象类或实现类时,只需在各自的层次上进行扩展,而无需改动其他部分的代码。这种分离使得软件架构更加清晰、易于维护,同时也为未来的扩展和修改留下了足够的空间。 🤔
  

    掌握了这两种模式,您就像拥有了一双巧手,能够在软件开发的舞台上编织出更加精彩的作品。无论是面对复杂多变的业务需求,还是应对日新月异的技术革新,您都能凭借这些模式,构建出既稳定又灵活的软件架构。⭐
  

    现在,是时候把这些知识应用到实践中去了!不要害怕尝试新的设计模式,它们将为您的软件开发之旅注入新的活力。就像那激励人心的创新与变革的象征图一样,鼓励您勇于探索、敢于创新。把适配器模式和桥接模式加入您的设计工具箱,让它们成为您构建优雅软件架构的得力助手。😉
  

    👏 让我们一起迈向更加精彩的软件设计之路吧!在此助您在软件设计的海洋中乘风破浪。 🚢

相关文章:

适配器模式与桥接模式-灵活应对变化的两种设计策略大比拼

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自&#xff1a;设计模式深度解析&#xff1a;适配器模式与桥接模式-灵活应对变…...

Elasticsearch8搭建及Springboot中集成使用

1.搭建 1.1.下载地址 Elasticsearch&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch Kibana&#xff1a;https://www.elastic.co/cn/downloads/kibana 1.2.具体过程 下载安装包&#xff1a;访问上述链接&#xff0c;下载适合你操作系统的Elasticsearch和Ki…...

asp.net在线租车平台

说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于asp.net架构和sql server数据库 功能模块&#xff1a; asp.net在线租车平台 用户功能有首页 行业新闻用户注册车辆查询租车介绍访问后台 后台管理员可以进行用户管理 管…...

Beamer模板——基于LaTeX制作学术PPT

Beamer模板——基于LaTeX制作学术PPT 介绍Beamer的基本使用安装和编译用于学术汇报的模板项目代码模板效果图 Beamer的高级特性动态效果分栏布局定理环境 介绍 在学术领域&#xff0c;演示文稿是展示和讨论研究成果的重要方式。传统的PowerPoint虽然方便&#xff0c;但在处理复…...

性能测试-Jmeter中IF控制器使用

一、Jmeter控制器 分为两种类型&#xff1a; 控制测试计划执行过程中节点的逻辑执行顺序&#xff0c;如&#xff1a;循环控制器&#xff0c;if控制器等对测试计划中的脚本进行分组&#xff0c;方便Jmeter统计执行结果以及进行脚本的运行时控制等&#xff0c;如&#xff1a;吞…...

华为综合案例-普通WLAN全覆盖配置(2)

组网图 结果验证 在AC_1和AC_2上执行display ap all命令&#xff0c;检查当前AP的状态&#xff0c;显示以下信息表示AP上线成功。[AC_1] display ap all Total AP information: nor : normal [1] ExtraInfo : Extra information P : insufficient power supply ---…...

这里是一本关于 DevOps 企业级 CI/CD 实战的书籍...

文章目录 &#x1f4cb; 前言&#x1f3af; 什么是 DevOps&#x1f3af; 什么是 CI/CD&#x1f3af;什么是 Jenkins&#x1f9e9; Jenkins 简单案例 &#x1f3af; DevOps 企业级实战书籍推荐&#x1f525; 参与方式 &#x1f4cb; 前言 企业级 CI/CD 实战是一个涉及到软件开发…...

机器学习 - save和load训练好的模型

如果已经训练好了一个模型&#xff0c;你就可以save和load这模型。 For saving and loading models in PyTorch, there are three main methods you should be aware of. PyTorch methodWhat does it do?torch.saveSaves a serialized object to disk using Python’s pickl…...

【动态规划】【同余前缀和】【多重背包】[推荐]2902. 和带限制的子多重集合的数目

本文涉及知识点 动态规划汇总 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 C算法&#xff1a;滑动窗口总结 多重背包 LeetCode2902. 和带限制的子多重集合的数目 给你一个下标从 0 开始的非负整数数组 nums 和两个整数 l 和 r 。 请你…...

nginx介绍及搭建

架构模型 Nginx是由一个master管理进程、多个worker进程组成的多进程模型。master负责管理worker进程&#xff0c;worker进程负责处理网络事件&#xff0c;整个框架被设计为一种依赖事件驱动、异步、非阻塞的模式。 优势&#xff1a; 1、充分利用多核&#xff0c;增强并发处理…...

树莓派夜视摄像头拍摄红外LED灯

NoIR相机是一种特殊类型的红外摄像头&#xff0c;其名称来源于"No Infrared"的缩写。与普通的彩色摄像头不同&#xff0c;NoIR相机具备红外摄影和低光条件下摄影的能力。 一般摄像头能够感知可见光&#xff0c;并用于普通摄影和视频拍摄。而NoIR相机则在设计上去除了…...

Oracle19C静默安装教程

文章目录 一、安装前的准备1、安装Linux操作系统2、配置网络源或者本地源3、hosts文件配置 二、准备安装环境1、安装依赖包2、创建oracle用户组3、配置系统内核参数4、关闭selinux5、配置oracle用户环境6、修改用户的Shell限制 三、静默安装Oracle数据库1、创建oracle安装目录2…...

【机器学习】基于粒子群算法优化的BP神经网络分类预测(PSO-BP)

目录 1.原理与思路2.设计与实现3.结果预测4.代码获取 1.原理与思路 【智能算法应用】智能算法优化BP神经网络思路【智能算法】粒子群算法&#xff08;PSO&#xff09;原理及实现 2.设计与实现 数据集&#xff1a; 多输入多输出&#xff1a;样本特征24&#xff0c;标签类别4…...

Sora后时代文生视频的探索

一、写在前面 按常理&#xff0c;这里应该长篇大论地介绍一下Sora发布对各行业各方面产生的影响。不过&#xff0c;这类文章已经很多了&#xff0c;我们今天主要聊聊那些已经成熟的解决方案、那些已经可以“信手拈来”的成果&#xff0c;并以此为基础&#xff0c;看看Sora发布…...

指南:在各主流操作系统上安装与配置Apache Tomcat

指南&#xff1a;在各主流操作系统上安装与配置Apache Tomcat Apache Tomcat作为一款广受欢迎的开源Java Servlet容器&#xff0c;为用户提供了一个纯Java环境下的Web服务器和Servlet容器。本文将详细介绍如何在不同的操作系统上安装Apache Tomcat&#xff0c;并进行基本的配置…...

物联网的介绍

物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;是指通过互联网将物理设备、传感器、通信设备和软件系统相互连接&#xff0c;形成一个网络化的系统。它可以实现设备之间的数据交换、信息共享和远程控制&#xff0c;使得物理世界与数字世界紧密结合。 物…...

目标检测——YOLOR算法解读

论文&#xff1a;YOLOR-You Only Learn One Representation: Unifified Network for Multiple Tasks 作者&#xff1a;Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao 链接&#xff1a;https://arxiv.org/abs/2105.04206 代码&#xff1a;https://github.com/WongKinYiu/yolo…...

NVIDIA NCCL 源码学习(十三)- IB SHARP

背景 之前我们看到了基于ring和tree的两种allreduce算法&#xff0c;对于ring allreduce&#xff0c;一块数据在reduce scatter阶段需要经过所有的rank&#xff0c;allgather阶段又需要经过所有rank&#xff1b;对于tree allreduce&#xff0c;一块数据数据在reduce阶段要上行…...

Spark-Scala语言实战(4)

在之前的文章中&#xff0c;我们学习了如何在scala中定义无参&#xff0c;带参以及匿名函数。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言…...

ffmpeg不常用命令整理

最近做了许多有关音视频方面的工作&#xff0c;接触了一些不常用的命令&#xff0c;整理分享出来。 1.剪辑视频 ffmpeg -ss 1 -to 4 -accurate_seek -i input.mp4 -c:v copy output.mp4指定从视频中的第1秒开始&#xff0c;到第4秒结束的部分剪辑。 ss&#xff1a;指定开始时…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库&#xff0c;基于 mysql 库改进而来&#xff0c;具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点&#xff1a; 支持 Promise / async-await&#xf…...