Interesting questions with FSMs implemented in software...
Which of the many implementation patterns should you choose?
My preference is anything that avoids deeply nested if/the/else/switch statements, since they rapidly become a maintenance nightmare. (I've seen nesting
10 deep!).Also, design patterns that enable logging of events and states should be encouraged and left in the code at runtime. I've found them /excellent/ techniques for correctly deflecting blame onto the other party :)
Should you design in a proper FSM style/language and autogenerate the executable source code, or code directly in the source language? Difficult, but there are very useful OOP design patterns that make it easy.
And w.r.t. TDD, should your tests demonstrate the FSM's design is correct or that the implementation artefacts are correct?
Naive unit tests often end up testing the individual low-level implementation artefacts, not the design. Those are useful when refactoring, but otherwise are not sufficient.