morgancodes
morgancodes

Reputation: 25265

how do you folks handle complex state situations where order of operations is important?

I'm getting in to a situation where I have several interacting widgets (on a web UI), all of whom can be in multiple different states, and whose behavior depends on others the others. I'm running in to situations where, for example, a set of data gets sorted twice, or the data gets displayed before it's sorted, rather than the other way around. It's a little bit of a wack-a-mole problem, where I think I've simplified things and gotten it working, only to find out I've broken things somewhere else.

I have functions that do things like:

widgetAFunction
  load data into widget B
  tell widget B to sort the data
  tell widget B to display the data

My love of code reuse makes me want to do something like write a loadData function in widget A that goes something like this:

widgetBLoadDataFunction
  update data
  sort the data
  refresh the view

So that all widgetA has to do is call one function on widgetB. But then there are cases where I just want to sort the data, without updating the data, so I write:

widgetBSortFunction
  sort the data
  refresh the view

And then maybe I want a filter function

widgetBFilterFunction filter the data refresh the view

And maybe I want to be update the data but not sort it, so I have

widgetBNoSortLoadDataFunction
  update data
  refresh the view

It doesn't seem that complex, but I wind up with these really long, very brittle chains of function calls, or a bunch of very similar calls. As Martin Fowler would say, the code is getting a little smelly.

So, what other alternatives do I have? I did something on a recent project where I did a state machine kind of thing, where I registered a bunch of functions with a set of conditions, or states which would trigger their execution. That worked somewhat well, and I'm thinking that approach might be good to use again.

Does anyone know what I'm talking about here, and even better, can anyone point me toward some patterns that will help me get my head around this better?

Upvotes: 4

Views: 351

Answers (2)

dwc
dwc

Reputation: 24910

Fernando already mentioned FSMs, and gave good info and links. :)

In addition, I'll add that your classes should already incorporate enough state so that you're not worried about sorting twice, etc. I.e., widgetB.sort() should check if it's been sorted since last update and just return if so. There's practically no downside to doing this, and it can improve performance (and also guard consistency).

Upvotes: 0

Fernando Miguélez
Fernando Miguélez

Reputation: 11316

What you need is a finite state machine implementation. Basically every finite state machine needs:

  • Events that the program responds to
  • States where the program waits between events
  • Transitions between states in response to events
  • Actions taken during transitions
  • Variables that hold values needed by actions between events

A good article from IBM teachs you a way of implementing it by means of Javascript.

Edit: Here is a FSM builder, so you don't have to build your own.

Upvotes: 4

Related Questions