一盏黄黄旧旧的灯

一盏黄黄旧旧的灯

模板方法模式

模板方法模式(Template Method Pattern)是一种行为设计模式,它在父类中定义了一个算法的框架,允许子类在不改变结构的情况下重写某些步骤。这种模式体现了“封装不变部分,扩展可变部分”的原则,使得算法骨架在父类中得以统一,而具体的实现细节则交由子类根据需要去完成。

实现

在嵌入式开发中,模板方法模式可以用于处理那些具有相似流程但具体操作步骤有所差异的情况,比如各种设备驱动的初始化、数据采集与处理流程等。下面是一个基于C语言的模板方法模式在嵌入式开发中的实际应用例子,假设我们正在设计一组不同类型的传感器接口,它们的读取操作虽然总体流程相同(打开设备、读取数据、关闭设备),但具体实现细节(如寄存器地址、读取命令等)各不相同。

首先,定义一个抽象传感器基类(模板),其中包含一个readData模板方法:

// Sensor.h
#ifndef SENSOR_H
#define SENSOR_H

#include <stdint.h>

typedef struct _Sensor Sensor;

struct _Sensor {
    void (*init)(Sensor *sensor);     // 初始化传感器
    void (*cleanup)(Sensor *sensor);  // 清理资源

    // 模板方法:读取数据的基本流程
    void (*readData)(Sensor *sensor, uint16_t *data);
};

#endif /* SENSOR_H */

接着,为该基类实现通用的初始化和清理函数:

// Sensor.c
#include "Sensor.h"

void sensorInit(Sensor *sensor) {
    // 公共的初始化逻辑(例如:配置GPIO、中断等)
    sensor->init(sensor);
}

void sensorCleanup(Sensor *sensor) {
    // 公共的清理逻辑(例如:释放资源、禁用中断等)
    sensor->cleanup(sensor);
}

然后,定义一个具体的传感器子类(如温度传感器),并实现其特有的初始化、清理和数据读取方法:

// TemperatureSensor.h
#include "Sensor.h"

typedef struct _TemperatureSensor TemperatureSensor;

struct _TemperatureSensor {
    Sensor base;         // 继承Sensor基类
    uint8_t deviceAddr;  // 特有的设备地址
    // ... 其他特有属性
};

TemperatureSensor *createTemperatureSensor(uint8_t addr);

void destroyTemperatureSensor(TemperatureSensor *tempSensor);

// ... 实现其他特有方法

// TemperatureSensor.c
#include "TemperatureSensor.h"
#include "I2C.h"  // 假设有一个I2C库用于通信

static void temperatureInit(TemperatureSensor *tempSensor) {
    // 特有的初始化逻辑(例如:配置I2C通信参数、设置工作模式等)
}

static void temperatureCleanup(TemperatureSensor *tempSensor) {
    // 特有的清理逻辑
}

static void temperatureReadData(TemperatureSensor *tempSensor, uint16_t *data) {
    // 特有的读取数据逻辑,通过I2C读取温度传感器数据
    I2C_start(tempSensor->deviceAddr);
    I2C_writeReg(TEMP_REG_ADDR);  // 假设 TEMP_REG_ADDR 是温度寄存器地址
    *data = I2C_readWord();
    I2C_stop();
}

TemperatureSensor *createTemperatureSensor(uint8_t addr) {
    TemperatureSensor *tempSensor = (TemperatureSensor *) malloc(sizeof(TemperatureSensor));
    tempSensor->base.init = &temperatureInit;
    tempSensor->base.cleanup = &temperatureCleanup;
    tempSensor->base.readData = &temperatureReadData;
    tempSensor->deviceAddr = addr;
    return tempSensor;
}

void destroyTemperatureSensor(TemperatureSensor *tempSensor) {
    free(tempSensor);
}

最后,在主程序中使用模板方法来统一调用不同传感器的数据读取操作:

// main.c
#include "Sensor.h"
#include "TemperatureSensor.h"

int main() {
    TemperatureSensor *tempSensor = createTemperatureSensor(0x48);  // 假设温度传感器地址为0x48
    uint16_t temperatureData;

    sensorInit((Sensor *) tempSensor);  // 使用通用初始化方法
    tempSensor->base.readData((Sensor *) tempSensor, &temperatureData);  // 使用模板方法读取数据
    printf("Temperature: %d\n", temperatureData);

    sensorCleanup((Sensor *) tempSensor);  // 使用通用清理方法
    destroyTemperatureSensor(tempSensor);

    return 0;
}

小结

在这个例子中,Sensor类定义了传感器读取数据的通用流程(模板方法readData),而TemperatureSensor作为子类实现了这个模板方法的具体细节。主程序只需通过Sensor接口来操作不同类型的传感器,无需关心底层实现差异,从而实现了代码的复用和扩展性。

04-20 23:50