State machine of software design

Source: Internet
Author: User
Tags fsm

============================================================================

Original works. Agree to reprint.

Please be sure to indicate the original source and this statement in the form of a hyperlink when reproduced.

Please specify transfer from: http://yunjianfei.iteye.com/blog/

============================================================================


I. Introduction to the state machine

The concept of state machine in software design, usually refers to the finite state machine (English: Finite-state. Abbreviation:FSM) also known as the finite state of its own active machine , referred to as the state machine , is a finite state and the transfer between these States and the movement of the behavior of the mathematical model.

FSM (finite state machines) can be represented using a state machine diagram in UML. You can also use a state transfer table that resembles the following format, and so on. The most common representations are shown below: The combination of the current state (B) and the event (Y) indicates the next state (C).

State transfer Table

Current status →
Events ↓

Status A

Status B

Status C

Event X

...

...

...

Event Y

...

Status C

...

Event Z

...

...

...

The state machine has two very important concepts: state, event . Here is a simple example of a CD player:

CD Player Status Transfer table

Status →
Events ↓

Play

Time out

Stop it

Press the play key

...

Play

Play

Press the Stop key

Stop it

Stop it

...

Press the Pause key

Time out

...

...

With this table, we are able to understand the state machine very intuitively, such as the following:

1. Simple CD player generally has three kinds of status: Play, pause, stop

2. We operate on the CD player. Is the event, simply speaking, there are three kinds of events: Press Play, stop, pause button.

3. In different states of the CD player, different events (press different button) occur. The things that are triggered and the next state of the CD machine (that is, state transitions) are not the same.

4. According to the above table, if the CD player's current status is "play", then we press the play button. It will remain in a "play" state and no state transitions will occur. Suppose you press the pause key. The state transition is triggered. The CD player status is transferred to the paused state. Similarly. Pressing the stop key shifts to the stopped state.

two. How the state machine is implemented

In the software development process, in very many cases, we will be involved in the concept of "state", for example, monitoring Server software, the server will have: ' Power on ', ' shutdown ', ' high load ' and other states.

Perform the task of the software for each task. There will be "in the queue", "ready". "Execute", "Execute Complete", "Failed" status. Tasks in different states, the occurrence of different events, State migration and the corresponding logic is not the same, for example, in the "queue" state, the event "Cancel task", this time only need to move the task out of the queue. And the status is changed to "failed". The same, the event "Cancel task" occurs in the "Execute" state, you need to do a lot of work, such as recycling resources to perform tasks.

In general, the assumption that states are very small may not involve the concept of state machines.

But assume that the state, the event is very many. Assuming that the design is not good state machine, software development to the late will be very laborious.

It is also a problem for maintenance and upgrades.

The implementation of state machine is mainly in the following ways. Here I have the first chapter of the CD machine sample to do a simple implementation of the instructions.

Note: Here I mainly in Python or c written code to illustrate, the actual use. In whatever language it is, the key is logical thinking.

1. If...else ..... PS: The most tedious way of the Earth (personal very dislike)

#!/usr/bin/pythonclass cdstatus:running = 0 STOP = 1 PAUSE = 2class cdevent:press_running = 0 press_stop = 1 Press_pause = 2def do_change_stop (): #TODO someting and change CD status to stop print "Chang CD to ' Stop ' st  ATUs "Def do_change_running (): #TODO someting and change CD status to running print" Chang CD to ' running ' status "def Do_change_pause (): #TODO someting and change CD status to pause print "Chang CD to ' pause ' status" def dispather (cur R_status, Event): if Curr_status = = CDStatus.RUNNING:if Event = = CDEvent.PRESS_STOP:do_change_stop ( ) Elif Event = = CDEvent.PRESS_PAUSE:do_change_pause () elif Curr_status = = CDStatus.STOP:if E Vent = = CDEvent.PRESS_RUNNING:do_change_running () elif event = = CDEvent.PRESS_PAUSE:do_chan         Ge_pause () elif curr_status = = CDStatus.PAUSE:if Event = = CDEvent.PRESS_RUNNING:do_change_running () Elif event = = CDEvent.PRESS_STOP:do_change_stop () else:print "error!" def main (): Current_status = cdstatus.stop event = cdevent.press_running dispather (current_status, event) Retu RNIF __name__ = = "__main__": Main ()

Can see, this sample is extremely cumbersome. The if...else also needs to nest 2 layers, and the outer layer infers the state. The inner layer infers the event and finally passes the current state and the event that occurred, corresponding to the "CD Machine State Migration Table". Handle events and transfer status.

Such a way is not flexible. Because each state is added, add a heap of If. else's decision.


2. Switch...case ..... There is no switch syntax in Python, can be replaced with dict, here I use the General C language to describe the narrative.

The following code can be directly compiled execution, in Dispather, nested 2 layer switch. Similar to the above if: Else's structure, just replaced by switch.

#include <stdio.h> #include <stdlib.h> #include <string.h>typedef enum{STOP = 0, RUNNING, PAUSE,} cd_s Tate;typedef enum{press_running = ' 0 ', press_pause = ' 1 ', press_stop = ' 2 ',} Cd_event;char state_to_str[3][100] = {"ST OP "," RUNNING "," PAUSE "};//global variable. Used to store CD current state int current_state = Stop;void do_change_running () {printf ("CD status from%s to runing\n", State_to_str[curren  T_state]); Current_state = RUNNING;}  void Do_change_stop () {printf ("CD Status from '%s ' to Stop\n", state_to_str[current_state]); Current_state = STOP;}  void Do_change_pause () {printf ("CD Status from '%s ' to pause\n", state_to_str[current_state]); Current_state = PAUSE;} int Dispather (current_state, event) {switch (current_state) {case Stop:switch (event) {case Press_run          Ning:do_change_running ();        Break          Case Press_pause:do_change_pause ();        Break          default:printf ("CD ' s state is not change\n");      Break }     Break          Case Pause:switch (Event) {case press_running:do_change_running ();        Break          Case Press_stop:do_change_stop ();        Break          default:printf ("CD ' s state is not change\n");      Break    } break;          Case Running:switch (Event) {case press_pause:do_change_pause ();        Break          Case Press_stop:do_change_stop ();        Break          default:printf ("CD ' s state is not change\n");      Break    } break; default:printf ("error!      No such status!\n ");  Break  }}int Main () {char ch = ' 0 ';  printf ("Please enter the digital Operation CD Machine (0:running, 1:pause, 2:stop): \ n");    while (1) {ch = GetChar (); if (ch = = ' \ n ') {} else if (Ch < ' 0 ') | |    (Ch > ' 3 ')) {printf ("illegal input.      Please enter!\n again ");    Continue      } else {char event = ch;      Dispather (Current_state, event); printf ("Please enter the digital Operation CD Machine (0:running, 1:pause, 2:stop): \ n");   }} return 0;} 

3. function pointer method . This is the way I use the most often, but also the favorite.

So here I will post the C and Python code separately, specific explanation.

Careful observation of the first chapter of the "CD Machine state transition Diagram", it is actually a two-dimensional matrix structure, the two-dimensional matrix structure corresponding to the data structure, is nothing more than a two-dimensional array. There are logical processes in state transitions, so we can use a "two-dimensional function pointer" to implement a state transition diagram.

Here I do not use a two-dimensional array, using a struct array, so that the implementation is more intuitive.

Assume that there is a new state increase. Just add new states, events, and handler functions to the State_mechine array.

#include <stdio.h> #include <stdlib.h> #include <string.h>typedef enum{STOP = 0, RUNNING, PAUSE, Max_ State,} cd_state;typedef enum{press_running = 0, Press_pause, Press_stop, Max_event,} Cd_event;char state_to_str[3][1  XX] = {"STOP", "RUNNING", "PAUSE"};struct cd_state_mechine {int state;  int event; void (*func) (unsigned char *);}; void do_change_running (unsigned char * user_data), void do_change_stop (unsigned char * user_data), void Do_change_pause ( unsigned char * user_data); struct Cd_state_mechine state_mechine[] = {{RUNNING, press_running, NULL}, {RUNNING, press_s TOP, Do_change_stop}, {RUNNING, Press_pause, do_change_pause}, {pause, press_running, do_change_running}, {pause, press   _stop, Do_change_stop}, {PAUSE, press_pause, null}, {stop, press_running, do_change_running}, {stop, press_stop, null}, {STOP, Press_pause, Do_change_pause}, {-1,-1, null},};//global variable. Used to store CD current state int current_state = stop;void do_change_running (unsigned char * user_data) {PRintf ("CD Status from%s to runing\n", state_to_str[current_state]); Current_state = RUNNING;}  void Do_change_stop (unsigned char * user_data) {printf ("CD Status from '%s ' to Stop\n", state_to_str[current_state]); Current_state = STOP;}  void Do_change_pause (unsigned char * user_data) {printf ("CD Status from '%s ' to pause\n", state_to_str[current_state]); Current_state = PAUSE;}  int Dispather (current_state, event) {int i = 0; for (i = 0; State_mechine[i].state! =-1; i++) {if (current_state = = State_mechine[i].state && event = = State_      mechine[i].event) {void (*func) (unsigned char *);      func = State_mechine[i].func;      if (func! = null) {func (null);      } else {printf ("State is not change!\n");    } break;  }}}int Main () {char ch = ' 0 ';  printf ("Please enter the digital Operation CD Machine (0:running, 1:pause, 2:stop): \ n");    while (1) {ch = GetChar (); if (ch = = ' \ n ') {} else if (Ch < ' 0 ') | |    (Ch > ' 3 ')) {printf ("non-Input method.      Please enter!\n again ");    Continue      } else {int event = CH-' 0 ';      Dispather (Current_state, event);    printf ("Please enter the digital Operation CD Machine (0:running, 1:pause, 2:stop): \ n"); }} return 0;}

Write it down here temporarily. Back to the free, and then fill the Python version number of the state machine implementation.

State machine of software design

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.