Using finite state machines to design software
Designing software can be a bewildering and stressful experience. The initial creative steps are fraught with risk and uncertainty, since they define the entire course of development for a software project and affect its outcome and success.
When creating new software, many programmers find it easier to just start coding without any prior formal plan. Experience has convinced them that there may not be a design method appropriate for their project or that any formal planning wastes too much time without significantly enhancing the quality of the final product. However, the concerns for good software engineering and software quality indicate that any design method that is simple to use and that helps create better code and documentation should be welcomed by the majority of software practitioners.
A common approach these days is to apply design patterns when planning and implementing a software project. A finite state machine (FSM) is one design pattern; other patterns not discussed here include consumer/producer, message queuing, master/slave, and so forth. A variety of design patterns could be applicable at various stages of a software project, from the initial overall concept to the lowest level coding phase.
This article is a brief and practical tutorial in designing software using finite state machines. It will lead the reader from the initial design steps through the creation of source code. The employment of an FSM model has become fairly common in many software applications, particularly when a project specifies the use of the Unified Modeling Language (UML).
Note however, that this writing makes no other reference to UML and requires no exceptional knowledge other than basic programming concepts and some common sense.
All that is needed is some means to create a two-dimensional table.
Let's begin with the sales pitch for using the FSM design pattern:
• It's applicable to a large variety of software projects.
• It can be valuable at many stages of development, from top-level design to module coding.
• It provides a fairly rigorous strategy that yields a simple and consistent code structure.
• It creates a useful documentation and maintenance product that reflects the organization of the code.
• It can incorporate an effective debugging tool with minimal effort.
• It lends itself to design-by-committee and peer reviews.