设计模式之状态模式

设计模式之状态模式介绍:状态模式是一种行为模式,它与有限状态机的概念紧密相关;其主要思想是程序在任意时刻仅可处于几种有限的状态中。 在任何一个特定状态中, 程序的

欢迎大家来到IT世界,在知识的湖畔探索吧!

介绍:

状态模式是一种行为模式,它与有限状态机的概念紧密相关;其主要思想是程序在任意时刻仅可处于几种有限的状态中。 在任何一个特定状态中, 程序的行为都不相同, 且可瞬间从一个状态切换到另一个状态。 不过, 根据当前状态, 程序可能会切换到另外一种状态, 也可能会保持当前状态不变。 这些数量有限且预先定义的状态切换规则被称为转移

设计模式之状态模式

有限状态机


作用:

将业务模型抽象成一个有限状态机,减少大量的switch-caseif-else的使用,使得代码逻辑清晰,结构规整;


类比:

智能手机的按键和开关会根据设备当前状态完成不同行为:

  • 当手机处于解锁状态时, 按下按键将执行各种功能。
  • 当手机处于锁定状态时, 按下任何按键都将解锁屏幕。
  • 当手机电量不足时, 按下任何按键都将显示充电页面。

以BLE链路层状态机为例:

设计模式之状态模式

BLE链路层状态机

#include <stdio.h>
#include <assert.h>
#include <stdbool.h>

/*链路层状态*/
typedef enum
{
    SCAN,
    STANDBY,
    ADV,
    CONN,
    INIT,
}SM_STATE;

/*触发事件*/
typedef enum
{
    EVENT1,
    EVENT2,
    EVENT3,
    EVENT4,
    EVENT5,
    EVENT6,
    EVENT7,
    EVENT8,
    EVENT9,
}SM_EVENT;

/*回调*/
typedef void (*state_cb)(void);

/*状态表*/
typedef struct
{
    SM_EVENT event;
    SM_STATE cur_state;
    SM_STATE next_state;
    state_cb cb;
}SM_TABLE_T;

/*就绪态*/
static void standby_state(void)
{
    printf("Standby\r\n");
}

/*扫描态*/
static void scan_state(void)
{
    printf("Scan\r\n");
}

/*广播态*/
static void adv_state(void)
{
    printf("Adv\r\n");
}

/*连接态*/
static void conn_state(void)
{
    printf("Conn\r\n");
}

/*发起态*/
static void init_state(void)
{
    printf("Init\r\n");
}

/*状态表*/
SM_TABLE_T state_table[] =
{
    {EVENT1, STANDBY, SCAN, scan_state},
    {EVENT2, STANDBY, ADV, adv_state},
    {EVENT3, STANDBY, INIT, init_state},
    
    {EVENT4, SCAN, STANDBY, standby_state},
    {EVENT5, INIT, STANDBY, standby_state},
    {EVENT6, ADV, STANDBY, standby_state},
    {EVENT7, CONN, STANDBY, standby_state},

    {EVENT8 , ADV, CONN, conn_state},
    {EVENT9, INIT, CONN, conn_state},
};


/*状态机*/
typedef struct
{
    SM_STATE cur_state;
    SM_TABLE_T* table;
    int size;
}SM_T;

/*事件处理及状态切换*/
void event_handle(SM_EVENT event, SM_T* sm)
{
    assert(sm != NULL && sm->table != NULL);

    bool find_flag = false;
    for (unsigned char i = 0; i < sm->size; i++)
    {
        if(sm->table[i].event == event && sm->table[i].cur_state == sm->cur_state)
        {
            sm->cur_state = sm->table[i].next_state;
            sm->table[i].cb();
            find_flag = true;
            break;
        }
    }

    if(!find_flag)
    {
        printf("Event wrong!\r\n");
    }
}

void main(void)
{
    SM_T state_machine = {.cur_state = STANDBY, .table = state_table, .size = (sizeof(state_table) / sizeof(SM_TABLE_T))};

    printf("Init to READY\r\n");

    SM_EVENT input_event[] = {EVENT1, EVENT4, EVENT3, EVENT9, EVENT7, EVENT6, EVENT8};

    for (char i = 0; i < sizeof(input_event) / sizeof(SM_EVENT); i++)
    {
        event_handle(input_event[i], &state_machine);
    }
}

欢迎大家来到IT世界,在知识的湖畔探索吧!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/37228.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信