Writing Mobile Code Essential Software Engineering for Building Mobile Applications [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Writing Mobile Code Essential Software Engineering for Building Mobile Applications [Electronic resources] - نسخه متنی

Ivo Salmre

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید













What Is a State Machine?



Anyone who has taken courses in digital logic design will be intimately familiar with the concept of a "state machine." This book uses a simplified version of this state machine definition. If you are not yet familiar with state machines, the concept is relatively simple and you probably already intuitively understand how state machines work.


The "state" of your application can be defined as the aggregate of all of its variables. The values of all of an application's variables give it a unique state that will only be changed when some external event causes a change. Examples of these kinds of state-changing events are events such as a user pressing a key, a button being clicked, an event firing due to an incoming message, or even a timer event. At any given moment, your application is in a certain state. It will enter a new state when something perturbs that state. The state that your application is currently in plus the new input are used to determine the next state.


A state machine is a formal structuring of this reality. Instead of using all of the application variables as a broad definition of the application's state, a state machine creates a single variable and defines it as the holder of some important aspect of the application's state. This variable is usually a global or class-level integer enumeration (for example, int m_myApplicationState;) with a defined set of valid states. The great strength of the state machine approach is that it enables you to come up with an explicit definition of valid states for some aspect of your application and enforce proper behaviors as an application moves from one state to another. An application can have more than one state machine with each separate state machine governing some useful set of behaviors that need to be structured. An application without any state machines is really just an application with a great many state machines; each application-level variable effectively is its own state machine and all kinds of code can access and modify this state. State machines are used to take a set of related variables or behaviors and organize them in a logical and maintainable way. State machines = organized behavior.


Figure 5.1 shows a state machine schematic for a multiple-choice vocabulary teaching game. This example is used several times in this chapter. The application's behavior has been broken down into a few logical states. These logical states exist whether or not we choose to define them in a state machine. The state machine is just a formal definition of how the application operates. It enables us to think crisply about the different states the application can move through as the user interacts with it.



Figure 5.1. A state machine for a simple multiple-choice vocabulary game.


[View full size image]




Another way of viewing the different states of the application is by building a state transition table. This table lists the discrete states that the application can exist in and shows which state transitions are possible. Table 5.1 shows the list of states and transitions for our application.



Table 5.1. State Transitions for the Multiple-Choice Vocabulary Game


State



External Input



Next State



StartScreen


StartScreen


StartScreen


StartScreen



"Next Question" chosen by user


"Correct Answer" chosen by user


"Incorrect Answer" chosen by user


"End Game" chosen by user



AskQuestion


Illegal state transition!


Illegal state transition!


Illegal state transition!



AskQuestion


AskQuestion


AskQuestion


AskQuestion



"Next Question" chosen by user


"Correct Answer" chosen by user


"Incorrect Answer" chosen by user


"End Game" chosen by user



Illegal state transition!


CongratulateUser


ScoldUser


Illegal state transition!



CongratulateUser


CongratulateUser


CongratulateUser


CongratulateUser



"Next Question" chosen by user


"Correct Answer" chosen by user


"Incorrect Answer" chosen by user


"End Game" chosen by user



AskQuestion


Illegal state transition!


Illegal state transition!


StartScreen



ScoldUser


ScoldUser


ScoldUser


ScoldUser



"Next Question" chosen by user


"Correct Answer" chosen by user


"Incorrect Answer" chosen by user


"End Game" chosen by user



AskQuestion


Illegal state transition!


Illegal state transition!


StartScreen




Note


I have chosen to list all the permutations of State and External Inputs above to illustrate that not all state transitions need be valid. Rows above with the Next State marked as "Illegal state transition" are not permissible in our application. If the application somehow gets into one of these state transitions, some of the application logic is faulty. The state machine logic should throw an exception or at least raise a debugger assert if an invalid state transition is encountered. Identifying illegal state transitions can aid you in debugging your applications.


Listing 5.1 realizes in code the state machine defined above. The code should bear a close resemblance to the state transitions defined in Table 5.1 and Figure 5.1. In the function below, you will notice that the code for each of the state transitions has a commented-out function call. This function call represents work to do for the state transition and is commented out to allow the code below to compile as a self-contained unit; the implementation of the function calls is left to you. It is a useful design pattern to define your state transitions as a switch/case statement block. Each "case" statement represents a state transition and should call a function to perform any work necessary to accomplish the state transition. This kind of centralization and encapsulation of state management is the most powerful thing about state machines; you have a central place where all of the important application transitions are defined and processed.


Listing 5.1. Sample Code for State Machine for Multiple-Choice Game




class MyStateMachineClass
{
private enum GameState
{
StartScreen,
AskQuestion,
CongratulateUser,
ScoldUser
}
private GameState m_CurrentGameState;
//----------------------------------------------
//The state machine that drives our user interface
//and manages other application state based on the
//mode the user is currently in
//----------------------------------------------
private void StateChangeForGame(GameState newGameUIState)
{
//See which state the application is being brought into
switch(newGameUIState)
{
case GameState.StartScreen:
//If we are coming from a state that does not allow
//transition to this state, throw an exception
if ((m_CurrentGameState != GameState.CongratulateUser)
&& (m_CurrentGameState != GameState.ScoldUser))
{
throw new System.Exception("Illegal State Change!");
}
//UNDONE: Place code here to
// 1. Hide, Show, Move UI controls into place
// 2. Set up whatever variables/game state needed
// for this mode
//
// SetUpGameStateForStartScreen();
break;
case GameState.AskQuestion:
//If we are coming from a state that does not allow
//transition to this state, throw an exception
if ((m_CurrentGameState != GameState.StartScreen)
&& (m_CurrentGameState != GameState.CongratulateUser)
&& (m_CurrentGameState != GameState.ScoldUser))
{
throw new System.Exception("Illegal State Change!");
}
//UNDONE: Place code here to
// 1. Hide, Show, Move UI controls into place
// 2. Set up whatever variables/game state needed
// for this mode
//
// SetUpGameStateForAskQuestion();
break;
case GameState.CongratulateUser:
//If we are coming from a state that does not allow
//transition to this state, throw an exception
if (m_CurrentGameState != GameState.AskQuestion)
{
throw new System.Exception("Illegal State Change!");
}
//UNDONE: Place code here to
// 1. Hide, Show, Move UI controls into place
// 2. Set up whatever variables/game state needed
// for this mode
//
// SetUpGameStateForCongratulateUser();
break;
case GameState.ScoldUser:
//If we are coming from a state that does not allow
//transition to this state, throw an exception
if (m_CurrentGameState != GameState.AskQuestion)
{
throw new System.Exception("Illegal State Change!");
}
//UNDONE: Place code here to
// 1. Hide, Show, Move UI controls into place
// 2. Set up whatever variables/game state needed
// for this mode
//
// SetUpGameStateForScoldUser();
break;
default:
throw new System.Exception("Unknown state!");
}
//Store the new requested state as our current state
m_CurrentGameState = newGameUIState;
}
} //End class



/ 159