23種設計模式 之 State模式(狀態模式)[C語言實現]

iteye_18800發表於2012-11-14
一、概念定義

State模式:允許一個物件在其狀態發生改變時,改變它的行為。

State模式和Strategy模式非常相似,需要說明的是兩者的思想是一致的;只不過封裝的物件不同:State模式封裝的是不同的狀態,而Strategy模式封裝的是不同的演算法。

State模式主要解決的問題是:在開發過程中,時常遇到需要根據不同的狀態需要進行不同的處理操作的問題。大部分人採用的是switch-case語句進行處理的,這樣會造成分支過多。State模式採用了對這些不同狀態進行封裝的方式處理這類問題,當狀態發生變化時進行處理,再切換至另外一種狀態,也就是說將狀態切換的任務交給了狀態類去負責。

二、模式結構圖

圖1 State模式結構圖

三、場景設計

人的一生需經歷:嬰兒、青少年、中年、老年這幾個階段(狀態),每個階段對應的行為:嬰兒->喝奶青少年->學習中->工作老年->退休。請用程式模擬這個過程的變化。

四、C語言實現

// 結構體定義

// 人生狀態
typedef enum
{
    PSTATE_BABY,      // 嬰兒
    PSTATE_YOUNG,     // 青少年
    PSTATE_MIDDLE,    // 中年
    PSTATE_OLD,       // 老年
    PSTATE_TOTAL      // 狀態個數
}person_state_e;
// 人類:結構體
typedef struct
{
    ...
    int (*action)(void);     // 狀態對應的行為
    ...
}person_t;

// 狀態對應的行為

// 嬰兒狀態:喝奶, etc.
int drink(void)
{
    fprintf(stdout, "I am drinking milk!");
    return 0;
}
...
// 青少年狀態:學習, etc.
int study(void)
{
    fprintf(stdout, "I am study!");
    return 0;
}
...
// 中年狀態:工作, etc.
int work(void)
{
    fprintf(stdout, "I am working!");
    return 0;
}
...
// 老年狀態:退休, etc.
int retire(void)
{
    fprintf(stdout, "I am have been retired!");
    return 0;
}
...

// 狀態切換模組

 // 狀態切換
int setstate(person_state_e state, person_t *person)
{
    switch(state)
    {
        case PSTATE_BABY:
        {
            ...
            person.action = drink;
            ...
            break;
        }
        case PSTATE_YOUNG:
        {
            ...
            person.action = study;
            ...
            break;
        }
        case PSTATE_MIDDLE:
        {
            ...
            person.action = work;
            ...
            break;
        }
        case PSTATE_OLD:
        {
            ...
            person.action = retrie;
            ...
            break;
        }
        default:
        {
            return -1;
        }
   }
   return 0;
}

//State模式的使用

int main(int argc, const char *argv[])
{
    person_t person;

    memset(person, 0, sizeof(person));

    setstate(PSTATE_BABY, &person);
    person.action();
    ...

    setstate(PSTATE_YOUNG, &person);
    person.action();
    ...

    setstate(PSTATE_MIDDLE, &person);
    person.action();
    ...

    setstate(PSTATE_OLD, &person);
    person.action();
    ...

    return 0;
}

相關文章