在这里插入图片描述

每日一句正能量

幸福的本质不是惊天动地的狂喜,而是持续收集微小雀跃的能力。
大脑对剧烈刺激会快速适应,但对日常生活中细小的积极体验——阳光、好听的歌、一杯热茶——如果能刻意留意并品味,幸福感会持续累积。幸福不是山顶的烟花,而是沿途捡拾的闪亮石子。


一、引言:当嵌入式固件遇上领域驱动设计

嵌入式开发有一个长期存在的痛点:业务逻辑与硬件细节深度耦合。一个典型的"反模式"是:温度控制算法直接调用 HAL_ADC_Read(),电机调速逻辑里硬编码了 PWM 寄存器地址,状态机里混杂了按键扫描和 I2C 通信代码。当需要更换传感器型号、迁移到新的 MCU 平台、或者让非嵌入式背景的业务专家理解代码时,这种"面条式"代码的维护成本呈指数级增长。

领域驱动设计(Domain-Driven Design, DDD)由 Eric Evans 于 2003 年提出,最初面向企业级软件。其核心思想是:让软件结构匹配业务领域的结构,用业务语言(通用语言,Ubiquitous Language)驱动代码设计

在 HarmonyOS 生态中,随着设备类型从单一 MCU 扩展到分布式多终端协同,固件的业务复杂度急剧上升。一个智能家居控制器可能需要同时管理传感器网络、执行器控制、用户交互、云端通信、OTA 升级等多个业务领域。DDD 提供了一套系统化的方法,帮助我们在资源受限的嵌入式环境中,依然保持代码的清晰结构和业务表达能力。

本文将深入探讨 DDD 的核心概念——限界上下文(Bounded Context)聚合根(Aggregate Root)——如何在 C 语言嵌入式固件中落地,并给出完整的工程实践。


二、DDD 核心概念在嵌入式中的映射

2.1 四层架构的嵌入式适配

在这里插入图片描述

标准 DDD 推荐四层架构:用户接口层、应用层、领域层、基础设施层。 在嵌入式场景中,我们将其映射为:

DDD 标准层 嵌入式映射 典型内容
用户接口层 交互接口层 按键扫描、串口命令解析、蓝牙 GATT 服务、LCD 菜单
应用层 应用协调层 任务调度、状态机编排、用例流程控制、跨聚合协调
领域层 领域核心层 聚合根、实体、值对象、领域服务、业务规则、不变性约束
基础设施层 硬件抽象层 HAL 驱动、RTOS 接口、文件系统、网络协议栈、第三方 SDK

核心原则:领域层不依赖任何具体技术实现,只通过抽象接口与硬件抽象层交互。这种"依赖倒置"确保了业务逻辑可以在不修改的情况下,更换底层硬件平台。

2.2 限界上下文:划分业务边界

限界上下文(Bounded Context)是 DDD 战略设计的核心概念。它定义了一个明确的边界,在这个边界内,领域模型、术语、业务规则具有唯一确定的含义。

在这里插入图片描述

以智能家居控制器为例,我们可以识别出以下限界上下文:

核心域(Core Domain)

  • 设备管理上下文:管理传感器和执行器的生命周期、状态监控、配置管理

支撑域(Supporting Domain)

  • 网络通信上下文:WiFi/蓝牙连接管理、协议解析、数据包收发
  • 电源管理上下文:电池监测、功耗优化、休眠唤醒策略
  • 固件升级上下文:OTA 下载、固件校验、版本管理

通用域(Generic Domain)

  • 日志上下文:分级日志、环形缓冲区、远程输出
  • 配置上下文:参数存储、持久化、运行时加载
  • 安全上下文:加密解密、签名验证、访问控制

上下文映射关系

  • 核心域 ← 支撑域:通过**防腐层(ACL)**隔离,支撑域适配核心域接口
  • 核心域 ← 通用域:通过**共享内核(Shared Kernel)**直接复用通用能力
  • 支撑域之间:通过**领域事件(Domain Event)**异步通信,避免紧耦合

三、聚合根:业务一致性的守护者

3.1 聚合根的本质

聚合(Aggregate)是一组生命周期强一致、修改规则强关联的实体和值对象的集合。聚合根(Aggregate Root)是聚合中最核心的实体,外部只能通过聚合根来访问和修改聚合内的对象。

在这里插入图片描述

聚合根的核心职责

  1. 身份标识:具有全局唯一标识(如 motor_id
  2. 不变性约束守护:确保聚合内的业务规则始终满足
  3. 事务边界:所有对聚合内对象的修改必须通过聚合根,保证原子性
  4. 生命周期管理:创建、销毁聚合内的实体和值对象
3.2 嵌入式 C 语言实现:电机控制聚合根
/* motor_aggregate.h - 电机控制聚合根 */
#ifndef MOTOR_AGGREGATE_H
#define MOTOR_AGGREGATE_H

#include <stdint.h>
#include <stdbool.h>

/* ============================================================
 * 值对象 (Value Object):不可变,通过属性值定义相等性
 * ============================================================ */

/* 转速值对象 */
typedef struct {
    int32_t rpm;            /* 转速值 */
    uint32_t max_rpm;       /* 最大允许转速 */
} MotorSpeed_t;

/* 位置值对象 */
typedef struct {
    int32_t angle_deg;      /* 角度值 */
    int32_t min_angle;      /* 最小角度限制 */
    int32_t max_angle;      /* 最大角度限制 */
} MotorPosition_t;

/* 电流值对象 */
typedef struct {
    uint32_t milliamps;     /* 电流值(mA) */
    uint32_t overcurrent_threshold; /* 过流阈值 */
} MotorCurrent_t;

/* 温度值对象 */
typedef struct {
    int16_t celsius;        /* 温度值(摄氏度) */
    int16_t thermal_limit;  /* 热保护阈值 */
} MotorTemperature_t;

/* ============================================================
 * 实体 (Entity):具有本地标识,生命周期从属于聚合根
 * ============================================================ */

/* 转速控制器实体 */
typedef struct {
    uint8_t  controller_id; /* 本地标识 */
    MotorSpeed_t target_speed;
    MotorSpeed_t actual_speed;
    uint32_t     kp, ki, kd; /* PID参数 */
    void (*update_pid)(struct MotorSpeedController_* self, 
                       MotorSpeed_t target, MotorSpeed_t actual);
} MotorSpeedController_t;

/* 位置反馈实体 */
typedef struct {
    uint8_t  encoder_id;
    MotorPosition_t current_position;
    uint32_t resolution;    /* 编码器分辨率 */
    int32_t  (*read_encoder)(void); /* 读取编码器回调 */
} MotorPositionFeedback_t;

/* 电流监测实体 */
typedef struct {
    uint8_t  monitor_id;
    MotorCurrent_t current;
    uint32_t sampling_rate_hz;
    void (*sample)(struct MotorCurrentMonitor_* self);
} MotorCurrentMonitor_t;

/* 温度保护实体 */
typedef struct {
    uint8_t  protector_id;
    MotorTemperature_t temperature;
    bool     thermal_shutdown_active;
    void (*check_thermal)(struct MotorThermalProtection_* self);
} MotorThermalProtection_t;

/* ============================================================
 * 聚合根 (Aggregate Root):MotorAggregate_t
 * 外部只能通过聚合根访问和修改聚合内对象
 * ============================================================ */

typedef struct {
    /* 聚合根全局唯一标识 */
    uint32_t motor_id;
    char     motor_name[32];
    
    /* 聚合内的实体(只能通过聚合根访问) */
    MotorSpeedController_t   speed_controller;
    MotorPositionFeedback_t  position_feedback;
    MotorCurrentMonitor_t    current_monitor;
    MotorThermalProtection_t thermal_protection;
    
    /* 聚合状态 */
    bool     is_enabled;
    bool     is_faulted;
    uint32_t fault_code;
    
    /* 领域事件(内部使用) */
    void (*on_domain_event)(uint32_t motor_id, uint8_t event_type, void* data);
    
} MotorAggregate_t;

/* ============================================================
 * 聚合根工厂方法
 * ============================================================ */
MotorAggregate_t* MotorAggregate_Create(uint32_t motor_id, 
                                         const char* name,
                                         uint32_t max_rpm,
                                         int32_t min_angle,
                                         int32_t max_angle,
                                         uint32_t overcurrent_ma,
                                         int16_t thermal_limit_c);

/* ============================================================
 * 聚合根业务方法(唯一的外部访问入口)
 * 所有方法内部保证不变性约束
 * ============================================================ */

/* 设置目标转速(业务方法,非简单setter) */
int MotorAggregate_SetTargetSpeed(MotorAggregate_t* agg, int32_t rpm);

/* 设置目标位置(业务方法,包含运动规划) */
int MotorAggregate_SetTargetPosition(MotorAggregate_t* agg, int32_t angle_deg);

/* 使能/禁用电机 */
int MotorAggregate_Enable(MotorAggregate_t* agg, bool enable);

/* 周期更新(主循环调用) */
int MotorAggregate_Update(MotorAggregate_t* agg, uint32_t dt_ms);

/* 获取聚合状态(只读快照) */
int MotorAggregate_GetStatus(const MotorAggregate_t* agg, 
                                MotorSpeed_t* speed,
                                MotorPosition_t* position,
                                MotorCurrent_t* current,
                                MotorTemperature_t* temp);

/* 清除故障 */
int MotorAggregate_ClearFault(MotorAggregate_t* agg);

/* 销毁聚合 */
void MotorAggregate_Destroy(MotorAggregate_t* agg);

#endif /* MOTOR_AGGREGATE_H */
/* motor_aggregate.c - 聚合根实现 */
#include \"motor_aggregate.h\"
#include <string.h>
#include <assert.h>

/* ============================================================
 * 不变性约束检查(私有函数)
 * ============================================================ */

/* 检查转速约束 */
static bool CheckSpeedInvariant(const MotorSpeed_t* speed) {
    return (speed->rpm >= -(int32_t)speed->max_rpm) && 
           (speed->rpm <= (int32_t)speed->max_rpm);
}

/* 检查位置约束 */
static bool CheckPositionInvariant(const MotorPosition_t* pos) {
    return (pos->angle_deg >= pos->min_angle) && 
           (pos->angle_deg <= pos->max_angle);
}

/* 检查电流约束 */
static bool CheckCurrentInvariant(const MotorCurrent_t* current) {
    return current->milliamps < current->overcurrent_threshold;
}

/* 检查温度约束 */
static bool CheckTemperatureInvariant(const MotorTemperature_t* temp) {
    return temp->celsius < temp->thermal_limit;
}

/* ============================================================
 * 工厂方法
 * ============================================================ */
MotorAggregate_t* MotorAggregate_Create(uint32_t motor_id, 
                                         const char* name,
                                         uint32_t max_rpm,
                                         int32_t min_angle,
                                         int32_t max_angle,
                                         uint32_t overcurrent_ma,
                                         int16_t thermal_limit_c) {
    MotorAggregate_t* agg = (MotorAggregate_t*)malloc(sizeof(MotorAggregate_t));
    if (!agg) return NULL;
    memset(agg, 0, sizeof(MotorAggregate_t));
    /* 初始化聚合根标识 */
    agg->motor_id = motor_id;
    strncpy(agg->motor_name, name, sizeof(agg->motor_name) - 1);
    /* 初始化值对象(不可变属性) */
    agg->speed_controller.target_speed.max_rpm = max_rpm;
    agg->speed_controller.actual_speed.max_rpm = max_rpm;
    agg->position_feedback.current_position.min_angle = min_angle;
    agg->position_feedback.current_position.max_angle = max_angle;
    agg->current_monitor.current.overcurrent_threshold = overcurrent_ma;
    agg->thermal_protection.temperature.thermal_limit = thermal_limit_c;
    /* 初始化实体状态 */
    agg->speed_controller.controller_id = 1;
    agg->position_feedback.encoder_id = 1;
    agg->current_monitor.monitor_id = 1;
    agg->thermal_protection.protector_id = 1;
    agg->is_enabled = false;
    agg->is_faulted = false;
    agg->fault_code = 0;
    Log_Info(\"MotorAggregate created: id=%u, name=%s\", motor_id, name);
    return agg;
    }

/* ============================================================
 * 业务方法实现
 * ============================================================ */

/* 设置目标转速 */
int MotorAggregate_SetTargetSpeed(MotorAggregate_t* agg, int32_t rpm) {
if (!agg) return -EINVAL;
/* 业务规则1:故障状态下不允许设置转速 */
if (agg->is_faulted) {
Log_Warn(\"Motor %u: Cannot set speed while faulted (code=%u)\", 
agg->motor_id, agg->fault_code);
return -EFAULT;
}
/* 业务规则2:未使能时允许设置但不生效 */
if (!agg->is_enabled) {
Log_Debug(\"Motor %u: Speed set to %d but motor not enabled\", 
agg->motor_id, rpm);
}
/* 业务规则3:转速必须在允许范围内 */
MotorSpeed_t new_speed = {
.rpm = rpm,
.max_rpm = agg->speed_controller.target_speed.max_rpm
};
if (!CheckSpeedInvariant(&new_speed)) {
Log_Error(\"Motor %u: Speed %d exceeds limit +/-%u\", 
agg->motor_id, rpm, new_speed.max_rpm);
return -ERANGE;
}
/* 业务规则4:转速变化率限制(防冲击) */
int32_t delta = rpm - agg->speed_controller.target_speed.rpm;
int32_t max_delta = (int32_t)new_speed.max_rpm / 10; /* 每周期最大变化10% */
if (delta > max_delta) {
rpm = agg->speed_controller.target_speed.rpm + max_delta;
Log_Warn(\"Motor %u: Speed change rate limited to %d\", agg->motor_id, rpm);
} else if (delta < -max_delta) {
rpm = agg->speed_controller.target_speed.rpm - max_delta;
Log_Warn(\"Motor %u: Speed change rate limited to %d\", agg->motor_id, rpm);
}
/* 应用变更 */
agg->speed_controller.target_speed.rpm = rpm;
/* 发布领域事件 */
if (agg->on_domain_event) {
uint8_t event_data[4];
memcpy(event_data, &rpm, sizeof(rpm));
agg->on_domain_event(agg->motor_id, EVENT_SPEED_CHANGED, event_data);
}
Log_Info(\"Motor %u: Target speed set to %d RPM\", agg->motor_id, rpm);
return 0;
}

/* 周期更新(主循环调用) */
int MotorAggregate_Update(MotorAggregate_t* agg, uint32_t dt_ms) {
if (!agg) return -EINVAL;
if (!agg->is_enabled) return 0;
if (agg->is_faulted) return -EFAULT;
/* 步骤1:读取传感器(通过抽象接口,不直接访问硬件) */
if (agg->position_feedback.read_encoder) {
int32_t raw = agg->position_feedback.read_encoder();
agg->position_feedback.current_position.angle_deg = 
raw * 360 / (int32_t)agg->position_feedback.resolution;
}
/* 步骤2:电流采样 */
if (agg->current_monitor.sample) {
agg->current_monitor.sample(&agg->current_monitor);
}
/* 步骤3:温度检查 */
if (agg->thermal_protection.check_thermal) {
agg->thermal_protection.check_thermal(&agg->thermal_protection);
}
/* 步骤4:不变性约束检查 */
if (!CheckCurrentInvariant(&agg->current_monitor.current)) {
agg->is_faulted = true;
agg->fault_code = FAULT_OVERCURRENT;
Log_Error(\"Motor %u: OVERCURRENT fault! %u mA\", 
agg->motor_id, agg->current_monitor.current.milliamps);
return -EFAULT;
}
if (!CheckTemperatureInvariant(&agg->thermal_protection.temperature)) {
agg->is_faulted = true;
agg->fault_code = FAULT_THERMAL;
agg->thermal_protection.thermal_shutdown_active = true;
Log_Error(\"Motor %u: THERMAL fault! %d C\", 
agg->motor_id, agg->thermal_protection.temperature.celsius);
return -EFAULT;
}
if (!CheckPositionInvariant(&agg->position_feedback.current_position)) {
agg->is_faulted = true;
agg->fault_code = FAULT_POSITION_LIMIT;
Log_Error(\"Motor %u: POSITION LIMIT fault! %d deg\", 
agg->motor_id, agg->position_feedback.current_position.angle_deg);
return -EFAULT;
}
/* 步骤5:PID控制计算 */
if (agg->speed_controller.update_pid) {
agg->speed_controller.update_pid(&agg->speed_controller,
     agg->speed_controller.target_speed,
     agg->speed_controller.actual_speed);
     }
     /* 步骤6:执行输出(通过抽象接口) */
     /* ... 调用PWM输出接口 ... */
     return 0;
     }

/* 获取聚合状态(只读快照) */
int MotorAggregate_GetStatus(const MotorAggregate_t* agg, 
MotorSpeed_t* speed,
MotorPosition_t* position,
MotorCurrent_t* current,
MotorTemperature_t* temp) {
if (!agg) return -EINVAL;
if (speed)   memcpy(speed, &agg->speed_controller.actual_speed, sizeof(MotorSpeed_t));
if (position) memcpy(position, &agg->position_feedback.current_position, sizeof(MotorPosition_t));
if (current)  memcpy(current, &agg->current_monitor.current, sizeof(MotorCurrent_t));
if (temp)     memcpy(temp, &agg->thermal_protection.temperature, sizeof(MotorTemperature_t));
return 0;
}

四、防腐层:隔离外部依赖

4.1 防腐层(ACL)设计

在这里插入图片描述

防腐层(Anti-Corruption Layer, ACL)是 DDD 中用于隔离核心域与外部系统(第三方库、遗留系统、硬件驱动)的关键模式。其核心思想是:领域层只依赖抽象接口,具体实现由适配器提供

/* sensor_reader_interface.h - 领域层定义的抽象接口 */
#ifndef SENSOR_READER_INTERFACE_H
#define SENSOR_READER_INTERFACE_H

#include <stdint.h>

/* 领域层定义的传感器读取接口 */
typedef struct {
    /* 读取温度 */
    int (*read_temperature)(void* self, int16_t* temp_c);
    /* 读取湿度 */
    int (*read_humidity)(void* self, uint16_t* humidity_pct);
    /* 读取压力 */
    int (*read_pressure)(void* self, uint32_t* pressure_pa);
    /* 获取传感器状态 */
    int (*get_status)(void* self, uint32_t* status);
    /* 私有数据 */
    void* private_data;
    } SensorReader_Interface_t;

#endif
/* sht30_adapter.c - 防腐层:SHT30传感器适配器 */
#include \"sensor_reader_interface.h\"
#include \"sht30_driver.h\"  /* 第三方厂商SDK */
/* 适配器私有数据 */
typedef struct {
    uint8_t i2c_addr;
    uint32_t last_read_time;
    SHT30_Handle_t* driver_handle;
    } SHT30_AdapterData_t;
    /* 实现领域层接口:读取温度 */
    static int SHT30_ReadTemperature(void* self, int16_t* temp_c) {
    SensorReader_Interface_t* iface = (SensorReader_Interface_t*)self;
    SHT30_AdapterData_t* data = (SHT30_AdapterData_t*)iface->private_data;
    /* 调用第三方SDK */
    float temp_raw;
    int ret = SHT30_ReadTemperatureRaw(data->driver_handle, &temp_raw);
    if (ret != 0) return ret;
    /* 数据转换:浮点转定点(嵌入式优化) */
    *temp_c = (int16_t)(temp_raw * 100);  /* 0.01度分辨率 */
    data->last_read_time = Platform_GetTickMs();
    return 0;
    }
    /* 实现领域层接口:读取湿度 */
    static int SHT30_ReadHumidity(void* self, uint16_t* humidity_pct) {
    SensorReader_Interface_t* iface = (SensorReader_Interface_t*)self;
    SHT30_AdapterData_t* data = (SHT30_AdapterData_t*)iface->private_data;
    float hum_raw;
    int ret = SHT30_ReadHumidityRaw(data->driver_handle, &hum_raw);
    if (ret != 0) return ret;
    *humidity_pct = (uint16_t)(hum_raw * 100);  /* 0.01%分辨率 */
    return 0;
    }
    /* 实现领域层接口:读取压力(SHT30无压力传感器,返回不支持) */
    static int SHT30_ReadPressure(void* self, uint32_t* pressure_pa) {
    (void)self;
    (void)pressure_pa;
    return -ENOTSUP;  /* 该传感器不支持压力测量 */
    }
    /* 实现领域层接口:获取状态 */
    static int SHT30_GetStatus(void* self, uint32_t* status) {
    SensorReader_Interface_t* iface = (SensorReader_Interface_t*)self;
    SHT30_AdapterData_t* data = (SHT30_AdapterData_t*)iface->private_data;
    SHT30_Status_t drv_status;
    int ret = SHT30_GetDriverStatus(data->driver_handle, &drv_status);
    if (ret != 0) return ret;
     /* 将厂商状态码映射为领域通用状态 */
     *status = 0;
     if (drv_status.is_busy)     *status |= SENSOR_STATUS_BUSY;
     if (drv_status.has_error)   *status |= SENSOR_STATUS_ERROR;
    if (drv_status.is_calibrated) *status |= SENSOR_STATUS_CALIBRATED;
    return 0;
    }
    /* 工厂方法:创建SHT30适配器 */
    SensorReader_Interface_t* SHT30_Adapter_Create(uint8_t i2c_addr) {
    SensorReader_Interface_t* iface = (SensorReader_Interface_t*)malloc(sizeof(SensorReader_Interface_t));
    SHT30_AdapterData_t* data = (SHT30_AdapterData_t*)malloc(sizeof(SHT30_AdapterData_t));
    if (!iface || !data) {
    free(iface);
    free(data);
    return NULL;
    }
    data->i2c_addr = i2c_addr;
    data->driver_handle = SHT30_Init(i2c_addr);  /* 初始化厂商SDK */
    iface->read_temperature = SHT30_ReadTemperature;
    iface->read_humidity = SHT30_ReadHumidity;
    iface->read_pressure = SHT30_ReadPressure;
    iface->get_status = SHT30_GetStatus;
    iface->private_data = data;
    Log_Info(\"SHT30 adapter created at I2C addr 0x%02X\", i2c_addr);
    return iface;
    }

防腐层的价值

  • 当从 SHT30 更换为 BME280 传感器时,只需替换适配器实现,领域层代码完全不变
  • 领域层单元测试可以使用 Mock 适配器,无需真实硬件
  • 第三方 SDK 的版本升级不会影响领域层

五、领域事件:跨上下文通信

5.1 领域事件机制

在这里插入图片描述

领域事件(Domain Event)表示领域中发生了某些重要的事情,通常用过去时态命名,如 DeviceOnlineConfigChangedMotorFaulted

在嵌入式场景中,领域事件用于:

  • 跨限界上下文的异步通信
  • 状态变更的广播通知
  • 审计日志的记录触发
  • 告警系统的触发源
/* domain_event.h - 领域事件框架 */
#ifndef DOMAIN_EVENT_H
#define DOMAIN_EVENT_H
#include <stdint.h>
#define MAX_EVENT_LISTENERS  8
#define MAX_EVENT_QUEUE_SIZE 32
/* 领域事件类型 */
typedef enum {
EVENT_NONE = 0,
EVENT_DEVICE_ONLINE,
EVENT_DEVICE_OFFLINE,
EVENT_CONFIG_CHANGED,
EVENT_MOTOR_SPEED_CHANGED,
EVENT_MOTOR_FAULTED,
EVENT_SENSOR_READING,
EVENT_BATTERY_LOW,
EVENT_OTA_AVAILABLE,
EVENT_MAX
} DomainEventType_t;
/* 领域事件 */
typedef struct {
DomainEventType_t type;
uint32_t timestamp;
uint32_t source_id;     /* 事件源(如聚合根ID) */
uint8_t  payload[32];   /* 事件载荷 */
uint8_t  payload_len;
} DomainEvent_t;
/* 事件监听器回调 */
typedef void (*EventListener_t)(const DomainEvent_t* event, void* user_data);
/* API */
int DomainEvent_Init(void);
int DomainEvent_Subscribe(DomainEventType_t type, EventListener_t listener, void* user_data);
int DomainEvent_Unsubscribe(DomainEventType_t type, EventListener_t listener);
int DomainEvent_Publish(const DomainEvent_t* event);
int DomainEvent_Process(void);  /* 主循环中调用,分发事件 */
#endif
/* domain_event.c - 领域事件实现 */
#include \"domain_event.h\"
#include <string.h>
/* 环形事件队列 */
static DomainEvent_t g_eventQueue[MAX_EVENT_QUEUE_SIZE];
static uint8_t g_queueHead = 0;
static uint8_t g_queueTail = 0;
static uint8_t g_queueCount = 0;
/* 监听器注册表 */
typedef struct {
EventListener_t listener;
void* user_data;
bool active;
} ListenerEntry_t;
static ListenerEntry_t g_listeners[EVENT_MAX][MAX_EVENT_LISTENERS];
int DomainEvent_Init(void) {
memset(g_eventQueue, 0, sizeof(g_eventQueue));
memset(g_listeners, 0, sizeof(g_listeners));
g_queueHead = g_queueTail = g_queueCount = 0;
return 0;
}
int DomainEvent_Subscribe(DomainEventType_t type, EventListener_t listener, void* user_data) {
if (type >= EVENT_MAX || !listener) return -EINVAL;
for (uint8_t i = 0; i < MAX_EVENT_LISTENERS; i++) {
if (!g_listeners[type][i].active) {
g_listeners[type][i].listener = listener;
g_listeners[type][i].user_data = user_data;
g_listeners[type][i].active = true;
Log_Info(\"Event listener registered for type %u\", type);
return 0;
}
}
return -ENOSPC;  /* 监听器已满 */
}
int DomainEvent_Publish(const DomainEvent_t* event) {
if (!event || event->type >= EVENT_MAX) return -EINVAL;
/* 检查队列是否满 */
if (g_queueCount >= MAX_EVENT_QUEUE_SIZE) {
Log_Warn(\"Event queue full, dropping event type %u\", event->type);
return -EAGAIN;
}
/* 写入队列 */
uint8_t idx = g_queueTail % MAX_EVENT_QUEUE_SIZE;
memcpy(&g_eventQueue[idx], event, sizeof(DomainEvent_t));
g_eventQueue[idx].timestamp = Platform_GetTickMs();
g_queueTail++;
g_queueCount++;
return 0;
}
/* 主循环中调用,分发事件 */
int DomainEvent_Process(void) {
while (g_queueCount > 0) {
uint8_t idx = g_queueHead % MAX_EVENT_QUEUE_SIZE;
DomainEvent_t* event = &g_eventQueue[idx];
/* 分发到所有监听器 */
for (uint8_t i = 0; i < MAX_EVENT_LISTENERS; i++) {
if (g_listeners[event->type][i].active) {
g_listeners[event->type][i].listener(event, 
g_listeners[event->type][i].user_data);
}
}
g_queueHead++;
g_queueCount--;
}
return 0;
}

使用示例

/* 日志上下文订阅设备状态变更 */
static void OnDeviceStateChanged(const DomainEvent_t* event, void* user_data) {
(void)user_data;
switch (event->type) {
case EVENT_DEVICE_ONLINE:
Log_Info(\"Device %u came online at %u\", event->source_id, event->timestamp);
 break;
 case EVENT_DEVICE_OFFLINE:
 Log_Warn(\"Device %u went offline at %u\", event->source_id, event->timestamp);
 break;
 case EVENT_MOTOR_FAULTED:
 Log_Error(\"Motor %u faulted! Code: %u\", event->source_id, event->payload[0]);
  break;
  default:
  break;
  }
  }
  /* 初始化时注册监听器 */
  void LoggingContext_Init(void) {
  DomainEvent_Subscribe(EVENT_DEVICE_ONLINE, OnDeviceStateChanged, NULL);
  DomainEvent_Subscribe(EVENT_DEVICE_OFFLINE, OnDeviceStateChanged, NULL);
  DomainEvent_Subscribe(EVENT_MOTOR_FAULTED, OnDeviceStateChanged, NULL);
  }

六、HarmonyOS 中的 DDD 实践

在 HarmonyOS 生态中,DDD 可以与分布式能力深度结合:

/* harmonyos_ddd_device_manager.c - HarmonyOS分布式设备管理 */
#include \"distributed_scheduler.h\"
#include \"softbus_bus_center.h\"
/* 设备聚合根(分布式场景) */
typedef struct {
/* 本地标识 */
uint32_t local_device_id;
char device_name[64];
/* 分布式标识 */
char network_id[64];
NodeState_t distributed_state;
/* 能力集合(值对象) */
DeviceCapability_t capabilities;
/* 子设备聚合(本地连接的设备) */
MotorAggregate_t* motors[4];
SensorReader_Interface_t* sensors[8];
/* 领域事件发布 */
void (*publish_event)(DomainEventType_t type, uint32_t source_id, const void* data, uint8_t len);
} DistributedDeviceAggregate_t;
/* 分布式设备发现(领域服务) */
int DistributedDevice_DiscoverPeers(DistributedDeviceAggregate_t* device) {
/* 通过HarmonyOS软总线发现同组设备 */
DeviceInfo* peers = NULL;
uint32_t peer_count = 0;
int ret = SoftBus_GetAllNodeDeviceInfo(device->network_id, &peers, &peer_count);
if (ret != 0) return ret;
for (uint32_t i = 0; i < peer_count; i++) {
/* 为每个发现的设备创建领域事件 */
DomainEvent_t event = {
.type = EVENT_DEVICE_ONLINE,
.source_id = HashDeviceId(peers[i].devId),
.payload_len = strlen(peers[i].devId)
};
memcpy(event.payload, peers[i].devId, event.payload_len);
DomainEvent_Publish(&event);
}
SoftBus_FreeNodeDeviceInfo(peers);
return 0;
}
/* 分布式任务迁移(跨聚合协调) */
int DistributedDevice_MigrateTask(DistributedDeviceAggregate_t* from_device,
     uint32_t task_id,
     const char* target_device_id) {
		/* 1. 保存任务状态 */
		TaskStateSnapshot_t snapshot;
		Task_SaveState(task_id, &snapshot);
		/* 2. 序列化状态 */
		uint8_t serialized[256];
		uint16_t len = SerializeTaskState(&snapshot, serialized, sizeof(serialized));
		/* 3. 通过软总线发送迁移请求 */
		SoftBusMessage_t msg = {
		.type = SOFTBUS_MSG_TYPE_DATA,
		.channel = \"task_migration\",
		.payload = serialized,
		.payloadLen = len
		};
		int ret = SoftBus_SendMessage(target_device_id, &msg, NULL, 0);
		if (ret != 0) {
		Log_Error(\"Task migration failed: %d\", ret);
		return ret;
		}
		 /* 4. 发布领域事件 */
		 DomainEvent_t event = {
		 .type = EVENT_TASK_MIGRATED,
		 .source_id = from_device->local_device_id,
		 .payload_len = sizeof(task_id)
		 };
		 memcpy(event.payload, &task_id, sizeof(task_id));
		 DomainEvent_Publish(&event);
		 return 0;
		 }

七、DDD 在嵌入式中的价值评估

在这里插入图片描述

维度 传统分层 DDD分层 提升说明
可维护性 5 8 业务逻辑集中,修改影响范围可控
可测试性 4 9 依赖接口可Mock,无需真实硬件
可移植性 5 9 硬件抽象隔离,换平台只需换适配器
业务清晰度 3 9 代码结构直接反映业务结构
团队协作 4 8 业务专家与开发者使用同一语言
资源效率 8 6 函数指针和抽象层带来轻微开销

结论:DDD 在嵌入式中的核心价值不是性能优化,而是长期可维护性和团队协作效率。对于业务复杂、生命周期长、需要多人协作的嵌入式项目,DDD 的投入产出比极高。


八、实践建议与常见陷阱

8.1 实践建议
  1. 从核心域开始:不要试图一次性对所有代码应用 DDD,先选择业务最复杂、变更最频繁的核心域
  2. 保持适度:嵌入式资源受限,不要过度设计。值对象可以用结构体,聚合根可以用结构体+函数指针
  3. 接口优先:领域层只依赖接口,具体实现放在硬件抽象层
  4. 事件异步:领域事件使用环形缓冲区,避免阻塞主循环
  5. 文档同步:用 ADR(架构决策记录)记录限界上下文的划分理由
8.2 常见陷阱
陷阱 表现 解决方案
贫血模型 聚合根只有数据没有行为,变成"结构体容器" 将业务方法放入聚合根,实现充血模型
过度聚合 一个聚合包含过多实体,事务边界过大 按业务不变性约束拆分聚合
跨聚合引用 直接持有其他聚合根的指针 使用 ID 引用,通过领域服务协调
领域泄漏 应用层直接调用硬件驱动 严格分层,应用层只调用领域层接口
事件滥用 所有通信都用事件,导致系统难以追踪 只在真正需要解耦的场景使用事件

九、总结

领域驱动设计不是 Java 或 C# 的专利,在 C 语言嵌入式固件中同样可以落地。通过限界上下文划分业务边界、通过聚合根保证业务一致性、通过防腐层隔离外部依赖、通过领域事件实现跨上下文通信,我们可以在资源受限的 MCU 上构建出结构清晰、业务表达力强、长期可维护的固件架构。

在 HarmonyOS 分布式生态中,DDD 的价值更加凸显:当多个设备协同工作时,清晰的领域边界和一致的通用语言,是避免"分布式 spaghetti code"的关键。


转载自:https://blog.csdn.net/u014727709/article/details/162629758
欢迎 👍点赞✍评论⭐收藏,欢迎指正

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐