前言
我相信有很多像我一樣的小菜朋友在糾結,寫程序就像記一本流水賬,偶爾用點基礎數據結構改進一下程序效率,這完全看不到技術的存在,看不到成長,在下不才,願做一個敢出頭的小菜,分享一下我的體悟,歡迎各路大神來指點、敲打。
正文:我觀象山多嫵媚
象山本無奇,多情觀之現嫵媚。
對我們的程序也是這樣的,同樣的功能要求,大牛看來萬種風情,隨手拿下;小菜看來欲拒還迎, 直看得心花怒放,卻總不得美人心。
比喻不是很恰當,但感覺能說明一些問題:拿到功能需求以后的建模和體系結構的認識決定了小菜無力感,這里和大家討論一種后台程序模型以幫助大家整體把握部分后台程序。
以GSM網絡CAP信令簡化模型為例,模擬SCP網元:

在應用程序規模較小時,比如幾百行的控制台程序,完全可以用順序結構來實現,並且那往往是最合算的方式,狀態機和面向對象一樣,在較小規模應用時反而會增加程序的復雜度,但當規模繼續擴大時就應該構建一個模型來實現,通常采用狀態機來實現。
狀態機:記錄實例的當前狀態,不同狀態時接受不同的事件,根據當前狀態以及事件進行狀態遷移,使用時需要定義初始狀態與終止狀態以代表實例的啟動和終止。
針對當前實例定義FSM:
//枚舉狀態
enum FSM_STATE {INIT=1, RRBE, RRBE_SEND_ERR, RRBE_SEND_WAIT, RRBE_SEND_SUC, AC, AC_SEND_ERR, AC_SEND_WAIT, AC_SEND_SUC, CONTINUE, CONTINUE_SEND_ERR, CONTINUE_SEND_WAIT, CONTINUE_SEND_SUC, ERB, ERB_WAIT, ERB_RECV, ACR, ACR_WAIT, ACR_RECV, RC_SEND, END};
//定義狀態表,包含主狀態和子狀態
TABLE FSMTable[MAX_LEN][MAX_LEN] = {{INIT},{RRBE, RRBE_SEND_ERR, RRBE_SEND_WAIT, RRBE_SEND_SUC},{AC, AC_SEND_ERR, AC_SEND_WAIT, AC_SEND_SUC}, {CONTINUE, CONTINUE_SEND_ERR, CONTINUE_SEND_WAIT, CONTINUE_SEND_SUC}, {ERB, ERB_WAIT, ERB_RECV}, {ACR, ACR_WAIT, ACR_RECV}, {RC_SEND}, {END}};
//定義狀態映射表,用於從狀態映射相應的處理函數
TABLE FSM2Proc[MAX_LEN][MAX_LEN] = {...};
//狀態實例,包含狀態和呼叫實例
struct FSM_Instance{
FSM_STATE state;
Instance ins;
};
FSM_STATE GetFSMState(FSM_Instance* fsmins);
FSM_STATE UpdateFSM(FSM_Instance* fsmins, FSM_STATE state);
func_ptr GetMsgProcByFSM(FSM_STATE fsmstate);
//當狀態為INIT時處理實例,僅接受指定的事件
FSM_STATE FSM_INIT_PROC(FSM_Instance* fsmins, MSG* msg )
{
switch(msg.type)
{
case DATA_ERROR:
DoSomeThing(...);
UpdateFSM(fsmins, RC_SEND);
break;
case TimeOut:
DoSomeThing(...);
UpdateFSM(fsmins, RC_SEND);
break;
case TC_ABORT:
DoSomeThing(...);
UpdateFSM(fsmins, RC_SEND);
break;
default:
DoNothing();
break;
}
}
//收到消息后獲取當前實例狀態,並映射當前狀態對應的處理函數,將消息傳入狀態處理函數
void EventProcess(MSG* msg)
{
func_ptr func = GetMsgProcByFSM(GetFSMState(fsminstance));
func(fsminstance, msg);
}
//消息隊列,事件驅動程序中必要的組成部分,在線程的初始化工作完成以后循環處理消息,並根據消息中的實例號投遞給相應的實例處理,示例為簡化實現
void GetSCPMsg()
{
while(GetMsg(&msg))
{
EventProcess();
}
}
經過消息隊列和狀態機改裝以后的程序是不是清晰很多,個人感覺這個模型的優點是結構很清晰,更容易實現子功能的低耦合、高內聚,修改起來也很容易,破壞性被局限在固定的處理過程,缺點就是實現一個完整的狀態機和消息機制並不容易,使用不當反而會增加復雜度。
后記
這篇寫的不盡如人意,有很多地方講的不明不白,闡述這樣一個框架對我來說也是第一次,吃力是免不了的,希望各位多指點。
