From: ptkwt@... (Phil Tomson) Date: 2004-04-08T09:39:18+09:00 Subject: Re: building UIs with statecharts In article <40748346.70007@mail.ru>, Alexey Verkhovsky wrote: >Phil Tomson wrote: >> Do others use state-machines for [driving the logic of rich user interfaces]? > >Ain't know about Ruby [yet], but when writing thick GUIs in Java I use >state machines for anything bigger than a simple popup dialog. > >Resulting code is somewhat more verbose, but comes out rather stable due >to very clean separation of buttons and logic. > >In really complex situations, write a separate class for each state. I'm doing things this way. Each state has a do_action method that gets called to do tasks and then transition to next state based on user input and the results of the actions. All of the state classes are singletons. >Transition from state to state is then a factory method in the >originating state, which creates an instance of the destination state, >and passes control there. Main loop (translated to Ruby) is something like: > >state = InitialState.new >state = state.getNextState until state.final? > I've got a StateMachine class, here's most of it: class StateMachine include Observable def initialize(state=InitialState) @current_state = state end def handle_event(event_class) @current_state.instance.do_action(event_class) @current_state = @current_state.instance.next_state changed notify_observers(@current_state) end ... end As long as the State classes define a do_action method and a next_state accessor it's usable by this StateMachine class. Either the State class sets up a default next_state or it sets it's @next_state attrib during the call to do_action. I suppose I could just have do_action return the next_state, as well, but I think the way I have it looks a bit clearer. Another nice consequence of doing things this way (with a state machine) is that you can set up some unit tests that test your state_machine without needing to have the GUI connected up. That way you can thoroughly test your logic without needing to do a whole bunch of GUI testing to get at it. (of course you'll still need to do final GUI testing, but perhaps not as much, besides, I'm not sure how to setup unit tests for a GUI otherwise, I suspect there are ways, but they're probably very specific to the toolkit being used or you have to have a GUI testing tool). Phil