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

Java二十三种设计模式-观察者模式(15/23)

观察者模式:实现对象间的松耦合通知机制

引言

在当今的软件开发领域,设计模式已成为创建可维护、可扩展和可重用代码的基石。在众多设计模式中,观察者模式以其独特的能力,实现对象间的松耦合通信而脱颖而出。本文将深入探讨观察者模式,一种允许对象状态变更自动通知依赖对象的行为型设计模式。我们将从其基本定义入手,阐释为何在现代软件架构中观察者模式至关重要,包括它如何实现解耦、动态交互和广播通信。接下来,文章将详细介绍观察者模式的组成部分,并通过Java代码示例展示其实现。此外,将讨论观察者模式的使用场景、优点与缺点,以及与其他设计模式的比较,最终提供一系列最佳实践和建议,以指导读者在适合的场景下有效运用观察者模式。无论您是资深架构师还是初出茅庐的开发者,本文都将为您提供宝贵的洞见,帮助您在构建复杂系统时做出更明智的设计选择。

 基础知识,java设计模式总体来说设计模式分为三大类:

(1)创建型模式,共5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

(2)结构型模式,共7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

(3)行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

第一部分:观察者模式概述

1.1 定义与用途

观察者模式的基本定义

观察者模式(Observer Pattern)是一种行为型设计模式,主要用于实现对象间的一对多通信。当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。

观察者模式是一种行为型设计模式,它定义了对象之间的一对多依赖关系,当一个对象状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式主要用于实现分布式系统中的对象通信。

解释为何需要观察者模式

  • 解耦:观察者模式可以将观察者和主题之间的依赖关系降至最低,实现松耦合。
  • 动态交互:允许对象在运行时动态地添加或移除观察者,增加了系统的灵活性。
  • 广播通信:当主题对象状态发生变化时,可以自动通知所有注册的观察者,实现广播通信。

1.2 观察者模式的组成

主题(Subject)

  • 定义:主题是观察者模式的核心,它维护了一系列观察者对象,并在状态发生改变时通知它们。
  • 职责:提供注册、移除和通知观察者的方法。

观察者(Observer)

  • 定义:观察者是一个接口,定义了观察者对象接收通知时需要实现的方法。
  • 职责:在接收到主题的通知后,更新自己的状态。

具体主题(Concrete Subject)

  • 定义:具体主题实现了主题接口,包含状态信息,并在状态改变时通知观察者。
  • 职责:存储状态信息,并在状态变化时调用观察者对象的更新方法。

具体观察者(Concrete Observer)

  • 定义:具体观察者实现了观察者接口,根据主题的当前状态进行相应操作。
  • 职责:接收来自主题的通知,并根据通知更新自己的状态或执行特定行为。

客户端(Client)

  • 角色:创建具体的观察者和主题对象,并将观察者注册到主题中。
  • 职责:组织主题和观察者之间的关联,但不参与它们之间的通信。

角色之间的交互

  • 注册与移除:观察者可以注册到主题中,也可以从主题中移除。
  • 状态变更通知:当具体主题的状态发生变化时,它会通知所有注册的观察者。
  • 更新行为:具体观察者接收到通知后,根据主题的当前状态执行更新行为。

观察者模式通过定义清晰的主题和观察者角色,以及它们之间的交互方式,实现了对象间的松耦合和动态通信。在下一部分中,我们将通过Java代码示例来展示观察者模式的具体实现。

第二部分:观察者模式的实现

2.1 Java实现示例

以下是使用Java语言实现观察者模式的代码示例。在这个示例中,我们将创建一个天气监测系统,其中WeatherData是主题,负责通知观察者天气变化;CurrentConditionsDisplay是观察者,根据接收到的天气信息更新显示。

// 观察者接口
interface Observer {void update(float temperature, float humidity, float pressure);
}// 主题接口
interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}// 具体主题
class WeatherData implements Subject {private List<Observer> observers;private float temperature;private float humidity;private float pressure;public WeatherData() {observers = new ArrayList<>();}@Overridepublic void registerObserver(Observer o) {observers.add(o);}@Overridepublic void removeObserver(Observer o) {int i = observers.indexOf(o);if (i >= 0) {observers.remove(i);}}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(temperature, humidity, pressure);}}public void measurementsChanged() {notifyObservers();}public void setMeasurements(float temperature, float humidity, float pressure) {this.temperature = temperature;this.humidity = humidity;this.pressure = pressure;measurementsChanged();}
}// 具体观察者
class CurrentConditionsDisplay implements Observer {@Overridepublic void update(float temperature, float humidity, float pressure) {System.out.println("Current conditions: " +"Temp: " + temperature + "F, " +"Humidity: " + humidity + "%, " +"Pressure: " + pressure + " mb");}
}// 客户端代码
public class Client {public static void main(String[] args) {WeatherData weatherData = new WeatherData();CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay();weatherData.registerObserver(currentConditionsDisplay);// 模拟天气数据变化weatherData.setMeasurements(80.6f, 65.0f, 30.4f);}
}

2.2 观察者模式中的角色和职责

观察者(Observer)

  • 职责:定义了一个更新接口,使得在主题状态改变时,观察者可以接收到通知。

主题(Subject)

  • 职责:维护观察者列表,提供注册和移除观察者的方法,并在状态改变时通知它们。

具体主题(Concrete Subject)

  • 职责:实现主题接口,存储状态信息,并在状态改变时通知观察者。

具体观察者(Concrete Observer)

  • 职责:实现观察者接口,根据接收到的状态信息执行相应的行为。

相互作用

  • 注册与移除:观察者可以注册到主题的观察者列表中,也可以从列表中移除。
  • 状态变更通知:主题在状态发生变化时,会遍历观察者列表并调用它们的更新方法。
  • 执行更新:观察者接收到通知后,根据主题的当前状态执行更新操作。

观察者模式允许对象间的松耦合,使得当一个对象状态发生变化时,所有依赖于它的对象都会得到通知。这种模式在需要实现事件驱动架构或发布-订阅模式的场景中非常有用。在下一部分中,我们将探讨观察者模式的使用场景。

第三部分:观察者模式的使用场景

3.1 需要对象间松耦合的场景

在软件设计中,对象间的松耦合是实现灵活、可维护系统的关键。观察者模式提供了一种机制,允许对象间的交互而不需要紧密耦合。

观察者模式的应用:

  • 事件驱动架构:在事件驱动的系统中,对象可能需要对某些事件做出响应,而不必显式依赖于事件的来源。
  • UI与业务逻辑分离:在图形用户界面编程中,界面组件(观察者)需要根据业务逻辑的变化(主题)更新显示,而不直接依赖于业务逻辑的具体实现。

应用实例:

  • 模型-视图-控制器(MVC):在MVC架构中,视图组件作为观察者,模型作为主题,当模型数据变化时,视图会自动更新。

3.2 需要自动更新多个依赖对象的场景

当系统中的一个对象状态发生变化时,可能需要自动更新所有依赖于该状态的对象。观察者模式通过主题与观察者的关系,实现了这种自动更新机制。

观察者模式的优势:

  • 自动更新:当主题对象状态变化时,所有注册的观察者都会自动收到通知并更新。
  • 减少手动管理:减少了手动更新每个依赖对象的需要,简化了代码逻辑。

应用实例:

  • 股票市场监控:在股票市场监控系统中,股票价格的变化(主题)需要实时更新所有监控器(观察者),如交易界面、数据分析工具等。

通过观察者模式,可以构建一个灵活的通信机制,使得对象之间的交互更加松散,同时确保了系统的高内聚性和低耦合性。这种模式在实际开发中非常有价值,尤其是在需要处理多个对象之间的复杂交互时。在下一部分中,我们将讨论观察者模式的优点与缺点。

第四部分:观察者模式的优点与缺点

4.1 优点

实现松耦合

  • 解耦对象:观察者模式允许对象之间的交互而无需紧密耦合,使得系统的组件更加独立。

提高系统的灵活性

  • 动态交互:可以在运行时动态地添加或移除观察者,使得系统能够灵活地响应变化。

广播通信

  • 状态变更通知:当主题的状态发生变化时,所有注册的观察者都会收到通知,实现广播通信。

易于扩展

  • 添加新观察者:可以轻松地添加新类型的观察者,而无需修改主题的代码。

易于维护

  • 分离关注点:将状态管理与状态变更的响应分离,使得各个部分更容易维护。

4.2 缺点

循环依赖

  • 观察者与主题:如果不当使用,可能会导致观察者和主题之间的循环依赖问题。

系统性能影响

  • 通知开销:在有大量观察者时,通知机制可能会带来性能开销。

顺序依赖

  • 执行顺序:观察者的执行顺序可能难以控制,有时这可能会导致问题。

过度使用

  • 滥用模式:在不需要观察者模式的场景中使用它,可能会导致系统设计过于复杂。

难以管理大量观察者

  • 观察者管理:当观察者数量很多时,管理这些观察者可能会变得困难。

通知不同步

  • 并发问题:在多线程环境中,观察者的更新可能需要同步处理,以避免并发问题。

观察者模式提供了一种强大的通信机制,使得对象之间的交互更加灵活和松耦合。然而,合理使用观察者模式并避免其缺点是至关重要的。了解其优点和缺点可以帮助开发者根据具体需求和场景选择最合适的设计模式。在实际开发中,应根据具体情况灵活运用观察者模式,以达到最佳的设计效果。

第五部分:观察者模式与其他模式的比较

5.1 与发布-订阅模式的比较

发布-订阅模式(Pub-Sub Pattern)

  • 定义:发布-订阅模式是一种消息通信模式,其中消息的发送者(发布者)和接收者(订阅者)之间没有直接的耦合关系,消息通过一个中介(如消息队列或事件总线)传递。
  • 特点:允许多个订阅者接收发布者的消息,支持一对多的消息传递。

观察者模式

  • 定义:观察者模式是一种对象行为模式,其中一个对象(主题)的状态改变会通知所有依赖于它的对象(观察者)。
  • 特点:主题和观察者之间存在直接的耦合,通常是一对一或一对多的关系。

对比

  • 耦合度:发布-订阅模式中的耦合度更低,因为消息通过中介传递,而观察者模式中主题需要显式地管理观察者列表。
  • 消息传递:发布-订阅模式可以处理更复杂的通信场景,如消息过滤、异步消息传递等,而观察者模式通常用于同步更新。
  • 使用场景:发布-订阅模式适用于大规模的分布式系统,观察者模式适用于对象间相对简单的通信。

5.2 与状态模式的对比

状态模式(State Pattern)

  • 定义:状态模式是一种行为型设计模式,允许对象在其内部状态改变时改变其行为,看起来像是改变了其类。
  • 特点:通过将每个状态封装为一个单独的类,状态转换逻辑由外部控制。

观察者模式

  • 定义:如前所述,观察者模式用于在对象间实现松耦合的通信,以便在状态变化时通知依赖对象。

对比

  • 状态管理:状态模式专注于对象状态的管理以及状态变化时的行为变化,而观察者模式专注于状态变化的通信机制。
  • 行为变化:状态模式允许对象根据当前状态改变其行为,观察者模式则不涉及对象行为的变化,只负责通知。
  • 使用场景:状态模式适用于对象状态复杂且状态变化影响行为的场景,观察者模式适用于需要在多个对象间同步状态的场景。

观察者模式和发布-订阅模式、状态模式都提供了处理对象状态变化和通信的不同方法。每种模式都有其独特的用途和优势,选择使用哪种模式取决于具体的设计需求和场景。在下一部分中,我们将提供观察者模式的最佳实践和建议。

第六部分:观察者模式的最佳实践和建议

6.1 最佳实践

确保接口定义清晰

  • 明确契约:确保主题和观察者之间的接口定义清晰,避免因接口模糊导致的错误。

保持主题和观察者的解耦

  • 减少依赖:设计主题时,避免对观察者的具体实现有所依赖。

使用组合优于继承

  • 组合关系:考虑使用组合关系来构建主题和观察者,以提高灵活性。

管理观察者列表

  • 动态注册与移除:提供清晰的注册和移除观察者的机制,确保观察者列表的准确性。

考虑线程安全

  • 并发控制:在多线程环境中使用观察者模式时,确保线程安全。

定义通知顺序

  • 有序通知:如果观察者的执行顺序重要,定义一个逻辑来控制通知的顺序。

提供取消订阅机制

  • 自主控制:允许观察者在不再需要接收通知时取消订阅。

6.2 避免滥用

避免过度使用

  • 合理使用:仅在对象间确实需要松耦合通信时使用观察者模式。

避免循环引用

  • 检查循环:避免因观察者模式导致的循环引用问题。

避免性能问题

  • 性能考量:在观察者众多的情况下,考虑通知机制可能带来的性能问题。

避免复杂化设计

  • 简化设计:不要因为使用观察者模式而使系统设计过于复杂。

6.3 替代方案

使用事件总线

  • 解耦通信:事件总线提供了一种更加解耦的方式来处理事件和消息传递。

使用消息队列

  • 异步处理:对于需要异步处理的场景,消息队列可以是一个合适的选择。

使用状态模式

  • 状态变化:当对象的状态变化需要改变其行为时,可以考虑使用状态模式。

使用命令模式

  • 命令封装:对于需要将操作封装为对象的场景,命令模式可以提供帮助。

使用责任链模式

  • 处理链:当一个请求需要沿着处理链传递时,责任链模式可以定义对象间的传递顺序。

观察者模式是一种强大的设计模式,可以在对象间实现松耦合的通信机制。合理使用观察者模式并避免其缺点对于构建灵活、可维护的系统至关重要。了解其替代方案可以帮助开发者根据具体需求和场景选择最合适的设计模式。在实际开发中,应根据具体情况灵活运用观察者模式,以达到最佳的设计效果。

结语

观察者模式是一种强大的设计模式,用于在对象间实现松耦合的通信机制。通过本文的深入分析,希望读者能够对观察者模式有更全面的理解,并在实际开发中做出合理的设计选择。

博主还写了其他Java设计模式关联文章,请各位大佬批评指正:

(一)创建型模式(5种):

Java二十三种设计模式-单例模式(1/23)

Java二十三种设计模式-工厂方法模式(2/23)

Java二十三种设计模式-抽象工厂模式(3/23)

Java二十三种设计模式-建造者模式(4/23)

Java二十三种设计模式-原型模式(5/23)

(二)结构型模式(7种): 

Java二十三种设计模式-适配器模式(6/23)

Java二十三种设计模式-装饰器模式(7/23)

Java二十三种设计模式-代理模式(8/23)

Java二十三种设计模式-外观模式(9/23)

Java二十三种设计模式-桥接模式(10/23)

Java二十三种设计模式-组合模式(11/23)

Java二十三种设计模式-享元模式(12/23)

 (三)行为型模式(11种): 

Java二十三种设计模式-策略模式(13/23)

Java二十三种设计模式-模板方法模式(14/23) 

未完待续,持续更新中...... 

相关文章:

Java二十三种设计模式-观察者模式(15/23)

观察者模式&#xff1a;实现对象间的松耦合通知机制 引言 在当今的软件开发领域&#xff0c;设计模式已成为创建可维护、可扩展和可重用代码的基石。在众多设计模式中&#xff0c;观察者模式以其独特的能力&#xff0c;实现对象间的松耦合通信而脱颖而出。本文将深入探讨观察…...

opencv-python图像增强二:图像去雾(暗通道去雾)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、简介&#xff1a;二、暗通道去雾方案简述&#xff1a;三、算法实现步骤3.1最小值滤波3.2 引导滤波3.3 计算图像全局光强 四&#xff1a;整体代码实现五&#xf…...

自研Vue3低代码海报制作平台第一步:基础拖拽组件开发

学习来源&#xff1a;稀土掘金 - 幽月之格大佬的技术专栏可拖拽、缩放、旋转组件 - 著作&#xff1a;可拖拽、缩放、旋转组件实现细节 非常感谢大佬&#xff01;受益匪浅&#xff01; 前面我们学习了很多vue3的知识&#xff0c;是时候把它们用起来做一个有意思的平台&#xf…...

QT 的 QSettings 读写 INI 文件的示例

在Qt中&#xff0c;QSettings 类提供了一种便捷的方式来存储和访问应用程序的设置&#xff0c;这些设置可以存储在多种格式的文件中&#xff0c;包括INI、Windows注册表&#xff08;仅Windows平台&#xff09;、XML和JSON等。以下是一些使用 QSettings 读写INI文件的示例。 写…...

【零基础学习CAPL语法】——testStep:测试结果输出函数

文章目录 1.函数介绍2.在报告中体现 1.函数介绍 testStep——测试结果输出函数 2.在报告中体现 //testStep() void PrintTxMsg() {testStep("Tx","[%x] [%.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x]",Diag_Req.id,Diag_Req.byte(0),Diag_Req.byte(1),Di…...

8.5.数据库基础技术-规范化

函数依赖 函数依赖&#xff1a;给定一个X,能唯一确定一个Y,就称X决定&#xff08;确定&#xff09;Y,或者说Y依赖于X。 例如&#xff1a;YX*X函数&#xff0c;此时X能确定Y的值&#xff0c;但是Y无法确定X的值&#xff0c;比如x2,y4,但是y4无法确定x2。函数依赖又可扩展以下两…...

于博士Cadence视频教程学习笔记备忘

标签&#xff1a;PCB教程 PCB设计步骤 cadence教程 Allegro教程 以下是我学习该视频教程的笔记&#xff0c;记录下备忘&#xff0c;欢迎大家在此基础上完善&#xff0c;能回传我一份是最好了&#xff0c;先谢过。 备注&#xff1a; 1、未掌握即未进行操作 2、操作软件是15.…...

8.3.数据库基础技术-关系代数

并&#xff1a;结果是两张表中所有记录数合并&#xff0c;相同记录只显示一次。交&#xff1a;结果是两张表中相同的记录。差&#xff1a;S1-S2,结果是S1表中有而S2表中没有的那些记录。 笛卡尔积&#xff1a;S1XS2,产生的结果包括S1和S2的所有属性列&#xff0c;并且S1中每条记…...

【Vue3】vue模板中如何使用enum枚举类型

简言 有的时候&#xff0c;我们想在vue模板中直接使用枚举类型的值&#xff0c;来做一些判断。 ts枚举 枚举允许开发人员定义一组命名常量。使用枚举可以更容易地记录意图&#xff0c;或创建一组不同的情况。TypeScript 提供了基于数字和字符串的枚举。 枚举的定义这里不说了…...

组合求和2

题目描述&#xff1a; Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sum to target. Each number in candidates may only be used once in the combinati…...

Apple Maps现在可在Firefox和Mac版Edge浏览器中使用

Apple Maps最初只能在 Windows 版 Safari、Chrome 浏览器和 Edge 浏览器上运行&#xff0c;现在已在其他浏览器上运行&#xff0c;包括 Mac 版 Firefox 和 Edge。经过十多年的等待&#xff0c;Apple Maps于今年 7 月推出了新版地图应用的测试版&#xff0c;但只能在有限的浏览器…...

基于嵌入式Linux的数据库

数据库 数据库是在数据库管理系统和控制之下&#xff0c;存放在存储 介质上的数据集合。 基于嵌入式的数据库 基于嵌入式linux的数据库主要有SQlite&#xff0c; Firebird,Berkeley DB,eXtremeDB Firebird是关系型数据库&#xff0c;功能强大&#xff0c;支持存储过 程&…...

C# 使用LINQ找出一个子字符串在另一个字符串中出现的所有位置

一、实现步骤 遍历主字符串&#xff0c;使用IndexOf方法查找子字符串的位置。如果找到了子字符串&#xff0c;记录其位置&#xff0c;并且从该位置的后面继续查找。重复上述步骤直到遍历完整个字符串。 二、简单代码示例 using System; using System.Collections.Generic; usi…...

YOLOv8添加MobileViTv3模块(代码+free)

目录 一、理由 二、方法 &#xff08;1&#xff09;导入MobileViTv3模块 &#xff08;2&#xff09;在ultralytics/nn/tasks.py的函数parse_model中修改 &#xff08;3&#xff09;在yaml配置文件中写入 &#xff08;4&#xff09;开始训练&#xff0c;先把其他梯度关闭&…...

从概念到落地:全面解析DApp项目开发的核心要素与未来趋势

随着区块链技术的迅猛发展&#xff0c;去中心化应用程序&#xff08;DApp&#xff09;逐渐成为Web3时代的重要组成部分。DApp通过智能合约和分布式账本技术&#xff0c;提供了无需信任中介的解决方案&#xff0c;这种去中心化的特性使其在金融、游戏、社交等多个领域得到了广泛…...

仓颉编程入门 -- 泛型概述 , 如何定义泛型函数

泛型概述 , 如何定义泛型函数 1 . 泛型的定义 在仓颉编程语言中&#xff0c;泛型机制允许我们定义参数化类型&#xff0c;这些类型在声明时不具体指定其操作的数据类型&#xff0c;而是作为类型形参保留&#xff0c;待使用时通过类型实参来明确。这种灵活性在函数和类型声明中…...

SOC估算方法之(OCV-SOC+安时积分法)

一、引言 此方法主要参考电动汽车用磷酸铁锂电池SOC估算方法这篇论文 总结&#xff1a; 开路电压的测量需要将电池静止相当长的一段时间才能达到平衡状态进行测量。 安时积分法存在初始SOC的估算和累积的误差。 所以上述两种方法都存在一定的缺陷&#xff0c;因此下面主要讲…...

指针(下)

文章目录 指针(下)野指针、空指针野指针空指针 二级指针**main**函数的原型说明 常量指针与指针常量常量指针指针常量常量指针常量 动态内存分配常用函数**malloc****calloc****realloc****free** **void**与**void***的区别扩展&#xff1a;形式参数和实际参数的对应关系 指针…...

C# 浅谈IEnumerable

一、IEnumerable 简介 IEnumerable 是一个接口&#xff0c;它定义了对集合进行迭代所需的方法。IEnumerable 接口主要用于允许开发者使用foreach循环来遍历集合中的元素。这个接口定义了一个名为 GetEnumerator 的方法&#xff0c;该方法返回一个实现了 IEnumerator 接口的对象…...

mmdebstrap:创建 Debian 系统 chroot 环境的利器 ️

文章目录 mmdebstrap 的一般性参数说明 &#x1f4dc;mmdebstrap 的常见用法示例 &#x1f308;使用 mmdebstrap 的注意事项 ⚠️ &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f388;欢迎踏入我的博客世界&#xff0c;能与您在此邂逅&#xff0c;真是缘分使然&am…...

【Linux SQLite数据库】一、SQLite交叉编译与移植

SQLite 是一个用 C 语言编写的开源、轻量级、快速、独立且高可靠性的 SQL 数据库引擎&#xff0c;它提供了功能齐全的数据库解决方案。SQLite 几乎可以在所有的手机和计算机上运行&#xff0c;它被嵌入到无数人每天都在使用的众多应用程序中。此外&#xff0c;SQLite 还具有稳定…...

每天写两道(数组篇)移除元素、

27.移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k&#xff0c;要通过此题&#xff0c;您需要执行以下操作&#…...

Unity 使用 NewtonSoft Json插件报错

JsonReaderException: Unexpected character encountered while parsing value: . Path , line 0, position 0. 通过断点发现&#xff0c;头有一串ZWNBSP&#xff0c;这个是BOM格式的JSON。在文件下看不到。 解决方法&#xff1a;改编码格式&#xff0c;Remove BOM....

k8s 部署 Mysqld_exporter 以及添加告警规则

最近监控 mysql 数据库&#xff0c;用了 pmm-server、pmm-client 发现监控是真的不太好用&#xff0c;还是用回 prometheus 吧。 部署mysqld_exporter k8s 部署最新版本的 mysqld_exporter&#xff0c;支持的数据库版本 MySQL >5.6、MariaDB > 10.3。 先在数据库创建用…...

基于STM32开发的智能农业环境监测系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码控制代码应用场景 农田环境监测温室环境控制常见问题及解决方案 常见问题解决方案结论 1. 引言 智能农业环境监测系统通过集成多种环境传感器&#xff0c;实时监测土壤湿度、温度…...

【SQL】平均售价

目录 题目 分析 代码 题目 表&#xff1a;Prices ------------------------ | Column Name | Type | ------------------------ | product_id | int | | start_date | date | | end_date | date | | price | int | ---------------…...

存储器与CPU的连接

1.单块存储芯片与CPU的连接 单独的一块独立的存储芯片提供的线有&#xff1a;地址总线&#xff0c;数据总线&#xff0c;读写控制线&#xff0c;片选线&#xff0c;如果该存储器只有八根数据总线用于输出数据&#xff0c;而cpu一次可以读64位的数据呢&#xff1f; 我们可以将八…...

unity--webgl 访问本地index.html

目录 1:使用本地服务器 1.1 使用 Python 的 SimpleHTTPServer 1.2 使用 Node.js 的 http-server 2&#xff1a;让其他人通过 IP 地址来访问你的 Unity WebGL 项目 2.1: 确保服务器可访问 2.2 获取公共 IP 地址 2.3 配置本地服务器 1.使用 Python 的 SimpleHTTPServer 2…...

慢慢欣赏DPDK RTE_MAX_ETHPORTS的定义

DPDK代码里面&#xff0c;RTE_MAX_ETHPORTS是一个常见的宏定义&#xff0c;但是在.c和.h文件找不到其定义&#xff0c;在全文件搜索条件下&#xff0c;在config/meson.build找到这么一个定义 dpdk_conf.set(RTE_MAX_ETHPORTS, get_option(max_ethports)) 该宏定义是根据构建输…...

Java Nacos与Gateway的使用

Java系列文章目录 IDEA使用指南 Java泛型总结&#xff08;快速上手详解&#xff09; Java Lambda表达式总结&#xff08;快速上手详解&#xff09; Java Optional容器总结&#xff08;快速上手图解&#xff09; Java 自定义注解笔记总结&#xff08;油管&#xff09; Jav…...