单片机实现的观察者模式

参考考网上的博文,记录下观察者模式

观察者模式(Observer Pattern)是一种行为设计模式,其核心在于建立对象间的动态订阅-通知机制。

主要有被观察者和观察者,是一对多的关系。这种模式可用于传感器更新后,其他模块同步更新传感器数据的应用场景

.h文件

c 复制代码
#ifndef __APP_SENSOR_H
#define __APP_SENSOR_H



#include "stm32f4xx_hal.h"
#include "EventRecorder.h"

#define  OBSERVER_MAX_NUM 6

// 观察者回调函数类型
typedef void(*ObserverCallback)(int value);

// 主题(被观察者)
typedef struct
{
	ObserverCallback observers[OBSERVER_MAX_NUM];
  int count;
  int sensor_value;
} SensorSubject;


void sensor_attach(SensorSubject* subject, ObserverCallback callback);
void sensor_set_value(SensorSubject* subject, int value);
void sensorTest(void);
void sensor_attachTest(void);

.c文件

c 复制代码
#include "app_sensor.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "SEGGER_RTT.h"

// 初始化传感器主题
SensorSubject sensor =
{
	.observers = {0},
	.count =0,
	.sensor_value =0
};


// 附加观察者到主题
void sensor_attach(SensorSubject* subject, ObserverCallback callback)
{
	if(!subject || !callback)
	{
	printf("Invalid parameters!\n");
	return;
	}

	if(subject->count >= OBSERVER_MAX_NUM)
	{
	printf("Observers full!\n");
	return;
	}

 subject->observers[subject->count++] = callback;
}



// 更新传感器值并通知观察者
void sensor_set_value(SensorSubject* subject, int value)
{
	if(!subject)
	{
	printf("Invalid parameters!\n");
	return;
	}

	subject->sensor_value = value;

	// 遍历所有观察者进行通知
	for(int i = 0; i < subject->count; ++i)
	{
		if(subject->observers[i])
		{
		 subject->observers[i](subject->sensor_value); //核心
		}
	}
}


// 观察者1:显示模块
void display_update(int value)
{
	printf("[Display] Value: %d\n", value);
}

// 观察者2:日志模块回
void logger_update(int value)
{
  printf("[Logger] Value: %d\n", value);
}

// 观察者3:报警模块
void alarm_update(int value)
{
	if(value >100)
	{
	printf("[Alarm] Value %d exceeds limit!\n", value);
	}
}


void sensor_attachTest(void)
{
		  // 注册观察者
	 sensor_attach(&sensor, display_update);
	 sensor_attach(&sensor, logger_update);
	 sensor_attach(&sensor, alarm_update);
}


int lvalue = 50;
void sensorTest(void)
{
	// 模拟传感器数据更新
	sensor_set_value(&sensor,lvalue);
	lvalue++;
}

测试

c 复制代码
int main(void)
{
	int16_t i = 0;

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
	EventRecorderInitialize(EventRecordAll, 1U);
	EventRecorderStart();
  /* USER CODE END SysInit */
  DWT_Init();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
  sensor_attachTest();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
     HAL_Delay(500);
	 sensorTest();
		
    /* USER CODE BEGIN 3 */
		

  }
  /* USER CODE END 3 */
}

可以看到当传感器数据更新时,其他模块也都同步更新了传感器数据。

其核心在于更新传感器函数中,使用了函数指针,相当于在运行绑定的函数

相关推荐
WinstonMao3 小时前
STM32上电不能开机运行问题排查
stm32·单片机·嵌入式硬件
csg11077 小时前
PIC单片机高阶实战(四):PIC32MX串口与4G模块通信
单片机·嵌入式硬件·物联网
BackCatK Chen7 小时前
STM32保姆级入门教程|第3章:从新建工程到LED闪烁点灯(Hex生成+ST-Link/J-Link切换全攻略)
stm32·单片机·stm32cubeide·led 闪烁点灯·st-link/j-link
辰哥单片机设计8 小时前
MPU6050陀螺仪(STM32)
stm32·单片机·嵌入式硬件
我不是程序猿儿11 小时前
【嵌入式】stm32的时钟配置入门及切入
stm32·单片机·嵌入式硬件
是大强12 小时前
斯密特触发器作用
单片机
爱倒腾的老唐13 小时前
03、制作 STM32 最小系统
stm32·单片机·嵌入式硬件
悠哉悠哉愿意14 小时前
【物联网学习笔记】串口接收
笔记·单片机·嵌入式硬件·物联网·学习
灵魂尾巴.14 小时前
单片机数据存储器
单片机·嵌入式硬件
番茄灭世神15 小时前
空气质量检测仪项目笔记——硬件介绍
stm32·单片机·嵌入式·gd32·国产芯片