Refining the behavior
The last step brings the calculator statechart to the point at which it can actually compute expressions. However, it can handle only positive numbers. In the next step, I will add handling of negative numbers. This turns out to be perhaps the toughest problem in this design because the same button, '–' (minus), represents in some contexts the binary operator of subtraction and sometimes the unary operator of negation.
There are only two possible contexts in which '–' can unambiguously represent the negation rather than the subtraction: (1) in the "opEntered" state (as in the expression: 2 * 2 =), and (2) at the beginning of a new computation (as in the expression: 2*2=).
Figure 2.17: Two cases of handling negative numbers.
The solution to the first case (shown in Figure 2.17a) is simpler. We need one more state "negated2," which is entered when the operator is MINUS (note the use of the guard). Upon entry, this state sets up the display to show '–0' and subsequently does not clear the display when transitioning to the "operand2" state. This is a different behavior from "opEntered" because in this latter state the display must be cleared to prepare for entering of the second operand.
The second case in which '–' represents the negation is trickier because the specification "beginning of new computation" is much more subtle. Here it indicates the situation just after launching the application or after the user clicks Cancel but not when the calculator displays the result from the previous computation. Figure 2.17b shows the solution. A new state "begin" is created to capture the behavior specific to the "beginning of new computation" (note the initial transition pointing now to "begin" rather than to "operand1"). The rest of the solution is analogous as in the first case, except now the state "begin" plays the role of "opEntered."
Final touches
The calculator is almost ready now. The final touches (which I leave as an exercise) include adding Cancel-Entry transitions in appropriate contexts and adding an "error" state to capture overflows and division by zero. Figure 2.18 shows the final calculator state diagram.
Figure 2.18: The final calculator statechart.
