views:

102

answers:

2

Recently I was listening to a tech talk on clean coding. The speaker was a test engineer, who emphasized on avoiding the "if" statements in the code and use polymorphism as much as possible. Also he advocated against global states.

I quite agree with him, yet i need a clarification on replacing the global state and "if" statement using polymorphism for the below scenario,

I have 3 states in my document. I want to change the state of the UI components based on the document state. Right now, i use "if" blocks and an enumeration type holding the current state of document to transition the states of UI components.

eg:

enum DOC_STATE
{
DOC_STATE_A = 0,
DOC_STATE_B,
DOC_STATE_C
};

void QMainWindow::handleUi(_docState)
{
switch(_docState)
{
case (DOC_STATE_A):
{
menu.disable();
....
}
case (DOC_STATE_B):
{
menu.enable();
...
}
case (DOC_STATE_C):
{
...
}
}

I think i can have separate child classes for each state and have the handleUI() method in each class. Calling handleUi() method calls the right method call. But say i maintain these objects in my doc, how do i switch from one object to other each time there is a transition in state?

In other words, how to handle UI transition by tracking the change in state of document without using a global state and "if" or Switch statements?

I use Qt. Thanks.

A: 

I don't think I understand the problem because the answer is too trivial: you replace the pointer to your state instance with a new state instance and discard the old one.

Noah Roberts
+2  A: 

If you are using Qt, take a look at The Qt State Machine Framework and the State Machine Examples. No need to re-invent the wheel when your framework already provides a sports car :)

Adam W
I did look at the the Qt State Machine Framework. Isn't it still using a global state? if is said that the global states are against testability. Or they mean that the tester should know all the global states he should maintain before testing a method, for which he doesn't have any trace from API.
Arun
The states are "global" in respect to the `QStateMachine`, but you can have a state machine per model, view, or anything else you want. All you have to do is make the state machine a member and then the machine itself is not global so therefore the states it contains are not either. Any testing with a state machine can grow exponentially depending on the level at which the states change. The lower they are, the more things can change higher up based on the current state of one component.
Adam W