C语言 软件设计的七大原则,及其应用案例

1. 单一职责原则 (Single Responsibility Principle, SRP)

定义: 一个模块或函数应当只有一个引起变化的原因。

应用案例:

在嵌入式系统中,可以将传感器数据的读取和处理分开成不同的函数。例如:

c 复制代码
// 读取传感器数据的函数
float read_temperature_sensor() {
    // 读取温度传感器数据的代码
    return temperature;
}

// 处理温度数据的函数
void process_temperature(float temperature) {
    // 处理温度数据的代码
}

void main() {
    float temperature = read_temperature_sensor();
    process_temperature(temperature);
}

2. 开放-封闭原则 (Open-Closed Principle, OCP)

定义: 软件实体(类、模块、函数等)应当对扩展开放,对修改封闭。

应用案例:

在嵌入式系统中,如果要增加新的传感器类型而不修改现有代码,可以使用函数指针来实现扩展。

c 复制代码
typedef float (*SensorReadFunction)();

float read_temperature_sensor() {
    // 读取温度传感器数据的代码
    return temperature;
}

float read_humidity_sensor() {
    // 读取湿度传感器数据的代码
    return humidity;
}

void read_and_process_sensor(SensorReadFunction read_function) {
    float sensor_data = read_function();
    // 处理传感器数据的代码
}

void main() {
    read_and_process_sensor(read_temperature_sensor);
    read_and_process_sensor(read_humidity_sensor);
}

3. 里氏替换原则 (Liskov Substitution Principle, LSP)

定义: 继承的子类应当能够替换其基类而不影响程序的正确性。

应用案例:

在嵌入式系统中,可以使用结构体和函数指针实现类似于面向对象的多态性。

c 复制代码
typedef struct {
    float (*read)();
} Sensor;

float read_temperature_sensor() {
    return temperature;
}

float read_humidity_sensor() {
    return humidity;
}

void read_and_process_sensor(Sensor *sensor) {
    float sensor_data = sensor->read();
    // 处理传感器数据的代码
}

void main() {
    Sensor temperature_sensor = {read_temperature_sensor};
    Sensor humidity_sensor = {read_humidity_sensor};

    read_and_process_sensor(&temperature_sensor);
    read_and_process_sensor(&humidity_sensor);
}

4. 接口隔离原则 (Interface Segregation Principle, ISP)

定义: 客户端不应该依赖于它不需要的接口。

应用案例:

在嵌入式系统中,可以将不同的功能分离成不同的接口,避免客户端依赖不需要的功能。

c 复制代码
typedef struct {
    float (*read_temperature)();
    float (*read_humidity)();
} Sensor;

float read_temperature() {
    return temperature;
}

float read_humidity() {
    return humidity;
}

Sensor sensor = {read_temperature, read_humidity};

void main() {
    float temperature = sensor.read_temperature();
    // 仅处理温度数据
}

5. 依赖倒置原则 (Dependency Inversion Principle, DIP)

定义: 高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

应用案例:

在嵌入式系统中,可以使用抽象接口来实现不同的传感器驱动,而不直接依赖具体的传感器实现。

c 复制代码
typedef struct {
    float (*read)();
} Sensor;

float read_temperature_sensor() {
    return temperature;
}

float read_humidity_sensor() {
    return humidity;
}

Sensor temperature_sensor = {read_temperature_sensor};
Sensor humidity_sensor = {read_humidity_sensor};

void read_and_process_sensor(Sensor *sensor) {
    float sensor_data = sensor->read();
    // 处理传感器数据的代码
}

void main() {
    read_and_process_sensor(&temperature_sensor);
    read_and_process_sensor(&humidity_sensor);
}

6. 迪米特法则 (Law of Demeter, LoD)

定义: 一个对象应该对其他对象有尽可能少的了解。

应用案例:

在嵌入式系统中,可以通过封装和接口隐藏实现细节,只暴露必要的功能给外部模块。

c 复制代码
typedef struct {
    float (*read)();
} Sensor;

typedef struct {
    Sensor sensor;
} Device;

float read_temperature_sensor() {
    return temperature;
}

Device create_device() {
    Sensor temperature_sensor = {read_temperature_sensor};
    Device device = {temperature_sensor};
    return device;
}

void read_and_process_device(Device *device) {
    float sensor_data = device->sensor.read();
    // 处理传感器数据的代码
}

void main() {
    Device device = create_device();
    read_and_process_device(&device);
}

7. 单元测试原则 (Unit Testing Principle)

定义: 编写可测试的代码,通过单元测试来验证每个模块或函数的功能。

应用案例:

在嵌入式系统中,可以使用模拟(mock)和桩(stub)来编写单元测试。

c 复制代码
// 原始函数
float read_temperature_sensor() {
    return temperature;
}

// 测试模拟函数
float mock_read_temperature_sensor() {
    return 25.0; // 模拟固定温度值
}

void process_temperature(float temperature) {
    // 处理温度数据的代码
}

void test_process_temperature() {
    float temperature = mock_read_temperature_sensor();
    process_temperature(temperature);
    // 验证处理结果
}

void main() {
    test_process_temperature();
}
相关推荐
源代码•宸22 分钟前
Leetcode—1266. 访问所有点的最小时间【简单】
开发语言·后端·算法·leetcode·职场和发展·golang
遇见~未来26 分钟前
JavaScript数组全解析:从本质到高级技巧
开发语言·前端·javascript
南屿欣风26 分钟前
Sentinel 熔断规则 - 异常比例(order & product 示例)笔记
java·开发语言
u01040583633 分钟前
使用Java实现高性能的异步编程:CompletableFuture与Reactive Streams
java·开发语言
朔北之忘 Clancy40 分钟前
2020 年 6 月青少年软编等考 C 语言二级真题解析
c语言·开发语言·c++·学习·青少年编程·题解·尺取法
消失的旧时光-19431 小时前
C++ 中的 auto 与 nullptr:不是语法糖,而是类型系统升级
开发语言·c++
专注VB编程开发20年1 小时前
c#Type数组转成字符串的名称
java·开发语言
HABuo1 小时前
【Linux进程(五)】进程地址空间深入剖析-->虚拟地址、物理地址、逻辑地址的区分
linux·运维·服务器·c语言·c++·后端·centos
编程饭碗1 小时前
【多线程编程】
java·开发语言
vyuvyucd1 小时前
Python虚拟环境终极指南:venv到uv进阶
开发语言·python·uv