Functional analysis with state machines
Sometimes, beginning with the state machine is the best approach for use case analysis. This is particularly true when the use case is obviously modal in nature, with different operational modes. This approach generally requires systems engineers who are very comfortable with state machines. This recipe is much like the previous use case analyses and can be used instead; the output is basically the same for all three of these recipes. The primary differences are that no activity diagram is created and the sequence diagrams are created from the executing use case state behavior.
Purpose
The purpose of the recipe is to create a set of high-quality requirements by identifying and characterizing the key system functions performed by the system during the execution of the use case capability. This recipe is particularly effective when the use case is clearly modal in nature and the systems engineers are highly skilled in developing state machines.
Inputs and preconditions
A use case naming a capability of the system from an actor-use point of view.
Outputs and postconditions
There are several outcomes, the most important of which is a set of requirements accurately and appropriately specifying the behavior of the system for the use case. Additional outputs include an executable use case model, logical system interfaces to support the use case behavior and a supporting logical data schema, and a set of scenarios that can be used later as specifications of test cases.
How to do it…
Figure 2.31 shows the workflow for this recipe. It is similar to the previous recipe. The primary difference is that rather than beginning the analysis by creating scenarios with the stakeholders, it begins by creating an activity model of the set of primary flows from which the scenarios will be derived:
Identify the use case
This first step is to identify the generic usage of which the scenarios of interest, user stories, and requirements are aspects.
Describe the use case
The description of the use case should include its purpose, a general description of the flows, preconditions, postconditions, and invariants (assumptions). Some modelers add the specific actors involved, user stories, and scenarios, but I prefer to use the model itself to contain those relations.
Identify related actors
The related actors are those people or systems outside our scope that interact with the system while it executes the current use case. These actors can send messages to the system, receive messages from the system, or both.
Define the execution context
The execution context is a kind of modeling sandbox that contains an executable component consisting of executable elements representing the use case and related actors. The recommended way to achieve this is to create separate blocks representing the use case and the actors, connected via ports. Having an isolated simulation sandbox allows different systems engineers to progress independently on different use case analyses.
Create ports and interfaces in the execution context
Once we have a set of scenarios, we've identified the flow from the use case to the actors and from the actors to the system. By inference, this identifies ports relating the actors and the system, and the specific flows within the interfaces that define them.
Create executable state model
This step identifies what I call the normative state machine. Executing this state machine can recreate each of the scenarios we drew in the Capture use case scenarios section of the Functional analysis with scenarios recipe. Almost all states, transitions, and actions represent requirements. Any state elements added only to assist in the execution that do not represent requirements should be stereotyped «non-normative» to clearly identify this fact. It is also common to create state behavior for the actors in a step known as instrumenting the actor to support the execution of the use case in the execution context.
Generate use case scenarios
The state model identifies multiple flows, driven by event receptions and transitions, executing actions along the way. A specific scenario takes a singular path through the state flow so that a single state machine model results in multiple scenarios. The scenarios are useful because they are easy to review with non-technical stakeholders and because they aid in the definition of the logical interfaces between the system and the actors. Because the state machine is executable, it can be automatically created from the execution of the state machine, provided that you are using a supportive tool.
Verify and validate requirements
Running the execution context for the use case allows us to demonstrate that our normative state machine in fact represents the flows identified by working with the stakeholder. It also allows us to identify flows and requirements that are missing, incomplete, or incorrect. These result in Requirements_change change requests to fix the identified requirements' defects.
Requirements_change
Parallel to the development and execution of the use case model, we maintain the textual requirements. This workflow event indicates the need to fix an identified requirement's defect.
Update the requirement set
In response to an identified requirements defect, we fix the textual requirements by adding, deleting, or modifying requirements. This will then be reflected in the updated model.
Add trace links
Once the use case model and requirements stabilize, we add trace links using the «trace» relation or something similar. These are generally backtraces to stakeholder requirements as well as forward links to any architectural elements that might already exist.
Perform a use case and requirements review
Once the work has stabilized, a review for correctness and compliance with standards may be done. This allows subject matter experts and stakeholders to review the requirements, use case, states, and scenarios for correctness, and for quality assurance staff to ensure compliance with modeling and requirements standards.
Example
Let's see an example.
The example used for this recipe is the Emulate Front and Rear Gearing use case. This use case is shown in Figure 2.32, along with some closely related use cases:
Describe the use case
All model elements deserve a useful description. In the case of a use case, we typically use the format shown in Figure 2.33:
Identify related actors
The related actors in this example are the Rider and the Training App. The rider signals the system to change the gearing via the gears control and receives a response in terms of changing resistance as well as setting the resistance mode to ERG or SIM mode. The training app, when connected, is notified of the current gearing so that it can be displayed, provides a simulated input of incline, and can optionally change between SIM and ERG modes. The relation of the actors to the use case is shown in Figure 2.32.
Define the execution context
The execution context creates blocks that represent the actors and the use case for the purpose of the analysis. In this example, the following naming conventions are observed:
- The block representing the use case has the use case name (with white space removed) preceded by
Uc_
. Thus, for this example, the use case block is named Uc_EmulateFrontandRearGearing. - Blocks representing the actors are given the actor name preceded with
a
and an abbreviation of the use case. For this use case, the prefix isaEFRG_
, so the actor blocks are named aEFRG_Rider and aEFRG_TrainingApp. - The interface blocks are named as <use case block>_<actor block>. The names of the two interface blocks are iUc_EmulateFrontandRearGearing_aEFRG_Rider and iUc_EmulateFrontandRearGearing_aEFRG_TrainingApp. The normal form of the interface block is associated with the proxy port on the use case block; the conjugated form is associated with the corresponding proxy port on the actor block.
All these elements are shown in the IBD in Figure 2.34:
Create ports and interfaces in the execution context
The (empty) ports and interfaces are added between the use case block and the actor blocks, as shown in Figure 2.34. These will be elaborated as the development proceeds in the next step.
Create an executable state model
Figure 2.35 shows the state machine for the Emulate Front and Rear Gearing use case. It is important to remember that the state machine is a restatement of textual requirements in a more formal language and not a declaration of design. The purpose of creating this state machine during this analysis is to identify requirement defects, not to design the system:
The use case block contains a number of system functions, value properties, and constants. These are shown in Table 2.2:
The behavior of the operations on the state machine are system functions. These must be elaborated for the purpose of simulation, and trace to requirements. For example, Figure 2.36 shows the behavior for the system functions that set up the defaults for the gearing for the rear cassette and front chain rings and the function that computes the gear inches when the gear is changed. This can be done in the action language used for the model (C++ in this case) or in activity diagrams. For this example, I used activity diagrams:
To support the simulation, the actor block aEFRG_Rider was instrumented with a state machine to interact with the use case block. This is shown in the following screenshot:
Generate use case scenarios
Scenarios are specific sequenced interaction sets that identify sequencing, timing, and values of different example users of a system. Sequence diagrams are generally easy to understand, even for non-technical stakeholders. In this recipe, sequences are created by exercising the use case state machine by changing the inputs to exercise different transition paths in the state machine. It is important to understand that there are usually an infinite set of possible scenarios, so we must constrain ourselves to consider a small representative set. The criteria we recommend is the minimal spanning set; this is a set of scenarios such that each transition path and action is executed at least once. More scenarios of interest can be added, but the set of sequences should at least meet this basic criterion.
Let's consider two different scenarios. The first (Figure 2.38) focuses on setting up the gearing for the bike prior to riding:
The second scenario shows the rider changing gears while riding in Figure 2.39:
Verify and validate requirements
The creation of the state machines in the previous section and their execution allows us to identify missing, incorrect, or incomplete requirements. The panel diagram in Figure 2.40 allows us to drive different scenarios and to perform what if analyses to explore the requirements:
Requirements_change
Parallel to the development and execution of the use case model, we maintain the textual requirements. This workflow event indicates the need to fix an identified requirement's defect.
Update the requirement set
In this example, we'll show the requirements in a table in the modeling tool. Figure 2.41 shows the newly added requirements:
Add trace links
Now that we've identified the requirements, we can add them to the model and add trace links to the Emulate Front and Rear Gearing use case. This is shown in the table in Figure 2.42:
Perform a use case and requirements review
With the analysis complete and the requirements added, a review can be conducted to evaluate the set of requirements. This review typically includes various subject matter experts in addition to the project team.