keer_zu 发表于 2025-5-30 16:04

C语言的设计模式---状态机模式

在C语言中实现状态机模式(State Pattern)可以通过**函数指针+状态结构体**模拟面向对象的多态行为。以下是一个完整的示例,以电灯开关(On/Off)为例:


```
#include <stdio.h>

// 状态接口(模拟抽象类)
typedef struct State State;
struct State {
    void (*handle)(void *context); // 处理函数指针
};

// 上下文(持有当前状态)
typedef struct {
    State *current_state;
} Context;

// 具体状态:开
void on_state_handle(void *context);
State OnState = { .handle = on_state_handle };

// 具体状态:关
void off_state_handle(void *context);
State OffState = { .handle = off_state_handle };

//--- 状态行为实现 ---
void on_state_handle(void *context) {
    Context *ctx = (Context *)context;
    printf("灯已开,执行关闭操作\n");
    ctx->current_state = &OffState; // 切换到关状态
}

void off_state_handle(void *context) {
    Context *ctx = (Context *)context;
    printf("灯已关,执行开启操作\n");
    ctx->current_state = &OnState; // 切换到开状态
}

//--- 上下文操作 ---
void init_context(Context *ctx) {
    ctx->current_state = &OffState; // 初始状态为关
}

void request(Context *ctx) {
    ctx->current_state->handle(ctx); // 委托给当前状态处理
}

//--- 测试代码 ---
int main() {
    Context ctx;
    init_context(&ctx);

    // 模拟用户操作
    for (int i = 0; i < 4; i++) {
      request(&ctx); // 每次请求触发状态转换
    }

    return 0;
}
```

### 输出结果:


```
灯已关,执行开启操作
灯已开,执行关闭操作
灯已关,执行开启操作
灯已开,执行关闭操作
```

### 关键设计解析:

1. **状态接口(State)**
   * 使用函数指针 `handle`模拟虚函数
   * 所有具体状态必须实现该函数
2. **具体状态(OnState/OffState)**
   * 全局单例状态对象(避免重复创建)
   * 在 `handle()`中实现状态转移逻辑
3. **上下文(Context)**
   * 持有 `current_state`指针指向当前状态
   * `request()`方法委托给状态对象处理
4. **状态转移**
   * 在状态处理函数中直接修改 `context->current_state`
   * 符合开闭原则:新增状态无需修改上下文

### 扩展新状态步骤(以添加**闪烁状态**为例):


```
// 1. 定义新状态
void blinking_state_handle(void *context);
State BlinkingState = { .handle = blinking_state_handle };

// 2. 实现行为逻辑
void blinking_state_handle(void *context) {
    Context *ctx = (Context *)context;
    printf("闪烁中,切换到关闭状态\n");
    ctx->current_state = &OffState;
}

// 3. 在现有状态中添加转移(如在OnState中)
void on_state_handle(void *context) {
    /* ... */
    if(需要闪烁) ctx->current_state = &BlinkingState;
}
```

### 优势:

1. **解耦状态逻辑**:每个状态独立封装行为
2. **消除条件分支**:避免复杂的switch-case语句
3. **可扩展性**:符合开放封闭原则
4. **状态转移显式化**:转移逻辑在状态内部明确声明

> **经典应用场景**:TCP连接状态、工控系统流程、游戏AI行为、协议解析器等需要清晰状态转换逻辑的系统。
>
页: [1]
查看完整版本: C语言的设计模式---状态机模式