4 ms·
State machines are anti-modular. State machines are anti-abstraction. State machine code is hard to read.
by aristidb 15y ago
State machines are anti-modular.
State machines are anti-abstraction.
State machine code is hard to read.
- jerf 15y agoAll of these problems are solvable if you apply a bit of DRY, and use better languages. I would despair of trying to combine state machines and DRY without closures. The final remaining "hard to read" that remains after DRY is usually a reflection of the problem domain, not the solution domain. That's a barrier you can't pass through; if you got seven states and ten events, you've got seventy things to deal with, one way or another. (Which doesn't have to mean 70 literal handlers, but does usually mean still quite a number.)
- wvanbergen 15y agoIndeed. If you do not use a state machine in a situation like that, you either get very complicated code as well, or you conveniently do not implement some of the state transitions. That will always get back to you: "how can this ever happen?!" State machines force you to consider all possible state transitions. This makes sure that transitions are handled properly, or they are actively made impossible.
- JoeAltmaier 15y agoI reduced a buggy, crashing, network protocol (serial modem!) to a state machine (three actually) in 2 days; had it debugged in another few days and it chugged along like a workhorse for years. In the process all the bugs in the original code were revealed - literally a hundred cases unhandled or incompletely handled. The code I found had a dozen flags and enourmous runon procedures at every event entry point, totally unreadable. SO yes I am a keen fan of state machines. But I admit they dominate your code architecture and look funky. Closures are definitely a good thing, tho I haven't yet figured out the best pattern. Its good to have all the cases laid out in front of you, with each combination of state and event commented and discussed. What would that look like using closures?
- jerf 15y ago"It depends." Whether you should show every combo of state and event or not is a local decision. What closures really make easy is something like "I always set something up, do something, and tear it down", and it allows you to put the set up and teardown in one place. Or maybe it lets you put the "something" in one place and it's the setup and tear down that are different every time. Or maybe you've got multiple state machines that are talking to each other, and it makes it possible to abstract them from each other a bit. It isn't like there's one design that they enable that is impossible without them, it's more like, it's a tool without which I would really be stuck. But one concrete example: I have a state machine that manages connection to a network resource that requires a negotiation process. I have some code that would like to just use that connection, without having to manage it, and there are many ways to enter this code and many things it may want to do. During the connection process, if more requests come in, the connection state machine just stacks them up as closures to be executed when the machine completes its connection. (Or, called another way, notify the callers of an error.) These closures themselves contain other ones that have the details of how to back to their state machines and send a message along that particular socket to go back out to the right client along one of several protocols. None of this is impossible without closures, but keeping the machines ignorant of how the other machines work is a lot harder without them. OO can do it too, albeit with a different flavor. Without one of OO or closures is a pain, though.
- dustingetz 15y agowould love to see a blog post glancing at the 'before' code and overviewing the 'after' code. Even if it was just two pastes.
- forgotAgain 15y agoI disagree. State machines are anti-modular: By clearly defining the transitions from one state to another and when outputs can occur I see state machines as making it easier to develop modular applications. I don't see how it inevitably leads to non-modular code. State machines are anti-abstraction: If you're modeling a process then some things can't be abstracted. At some level you have to deal with real world situations. State machine code is hard to read: That's a function of the effort made to make it easy to read. It's no different than any other situation. In general I find state machine design to be helpful in literally controlling the state of an application. By limiting what an application does and when it can do it, via an easily understood mental model, it's a straight forward design technique.
- aristidb 15y ago> By clearly defining the transitions from one state to another and when outputs can occur I see state machines as making it easier to develop modular applications. I don't see how it inevitably leads to non-modular code. I have not seen a modular state machine yet. Perhaps it is possible, but it doesn't seem to be done very often. > If you're modeling a process then some things can't be abstracted. At some level you have to deal with real world situations. I don't think state machines are usually the most natural representation of a process. And very often, people use state machines to model things that don't really fit into that model. > That's a function of the effort made to make it easy to read. It's no different than any other situation. Perhaps I have only seen the bad apples.
- kreneskyp 15y agoThe problem is that many apps are looking at the wrong states when they design their machine. For instance I worked on an app someone had build in which states were based on a multi-page html form. When I added an android app allowing offline data collection, I then had to hack around the state machine. We couldn't just create a instance of the object with the final data, we had to write code that replicated the submissions of the html form.
- jbrechtel 15y ago
- dsadinoff 15y agoWhat about a .dot file? It's pretty simple. digraph publish{ AUTHOR -> EDIT EDIT -> PUBLISHED } voilla! a state diagram. What's that? you want metadata? digraph publish{ AUTHOR => EDIT [ key="SUBMIT" buttonText="Submit to Editor" privilegesRequired="SBMT" ] } et voilla. The modularity can find it's way in the code implementing the state machine actions. Not sure what "anti-abstraction" means, but I find the above pretty easy to read. Also, you get free diagrams via graphviz.
- rikthevik 15y ago> State machine code is hard to read. I disagree. A well-written state machine is largely declarative. And that's just as good as it gets for readability.
- dustingetz 15y agoguys, i think the parent makes more sense if you qualify as state machines suck if: - the problem isn't inherently stateful - the stateful code is not carefully written i think the problem is as the OP dscribes: people often write stateful code without realizing it, thus the code doesn't show explicit understanding the combinatorical number of state transitions and all the possible edge case bugs.
- SoftwareMaven 15y agoBut that just reduces to sucky code sucks and doesn't say anything meaningful about state machines.
- jleader 15y agoI don't think state machines are anti-modular, but I've seen situations where a cartesian product of several state machines was modeled as one big state machine, rather than as several largely independent state machines running in parallel. The one big state machine ends up as an anti-modular un-abstracted hard to read mess. Imagine writing a state machine to handle TCP/IP connection establishment, and a state machine to handle parsing HTTP headers, and a state machine for the different things your web app can be doing. If you combine them all into one big state machine, you're going to have a huge mess. If you can write separate state-driven modules for each, interacting with each other at well-defined interfaces, you'll be much better off. In other words, state machines, like most tools, can be abused. Don't do that!
- husted 15y agoNone of these has to be true. Of cause I'm a bit colored on the subject since I once worked on visualSTATE (http://www.iar.com/website1/1.0.1.0/371/1/ http://www.iar.com/website1/1.0.1.0/371/1/) which is a graphical tool for state machines. In fact I see state machines in pretty much all software projects but developers are so attached to their way of thinking that they have troubles adopting to new programming concepts.