Overview
A Finite State Machine (FSM) is a mathematical model of computation that represents a system with a finite number of states, transitions between those states, and actions. FSMs provide a rigorous, visual way to design systems with well-defined behavior based on their current state and incoming events.
π― What is a Finite State Machine?
An FSM consists of:
- States: Finite set of conditions the system can be in (e.g., “Pending”, “Processing”, “Completed”)
- Transitions: Rules for moving from one state to another based on events/inputs
- Events/Inputs: Triggers that cause state changes (e.g., “Submit”, “Cancel”, “Approve”)
- Actions: Operations performed during transitions or while in a state (optional)
- Initial State: The starting point when the system begins
- Final States: Terminal states where the system ends (optional)
Key Principle: At any moment, the system is in exactly one state. State changes are explicit and predictable.
π Why Use Finite State Machines?
Clarity and Predictability:
- Explicit behavior: All possible states and transitions are documented
- No ambiguity: System behavior is deterministic for any input
- Visual representation: State diagrams are easy to understand and communicate
- Reduced bugs: Impossible states and transitions are prevented by design
Design Benefits:
- Easier testing: Test each state and transition independently
- Maintainability: Adding new states/transitions is straightforward
- Validation: Enforce business rules through state constraints
- Debugging: Current state makes troubleshooting easier
ποΈ Types of Finite State Machines
1. Deterministic Finite Automaton (DFA)
Characteristics:
- One transition per state-event pair: Given current state and event, next state is always the same
- Predictable: No randomness or ambiguity
- Most common: Used in most practical applications
Example (Order Processing):
States: Pending β Confirmed β Shipped β Delivered
Events: confirm, ship, deliver
Pending + confirm β Confirmed
Confirmed + ship β Shipped
Shipped + deliver β Delivered2. Non-Deterministic Finite Automaton (NFA)
Characteristics:
- Multiple possible transitions: Same state and event can lead to different states
- Ambiguous: Next state not always deterministic
- Less common: Theoretical importance, but converted to DFA for implementation
Example:
State A + event X β State B OR State C (non-deterministic)3. Hierarchical State Machine (HSM)
Characteristics:
- Nested states: States can contain sub-states
- Reduces complexity: Group related states together
- Inheritance: Sub-states inherit parent state transitions
Example (Authentication):
Authenticated (parent state)
βββ Active (sub-state)
β βββ Viewing
β βββ Editing
βββ Idle (sub-state)π§© FSM Components in Detail
States
Definition: Distinct modes of operation with specific behavior.
Good State Characteristics:
- Mutually exclusive: System can’t be in two states at once
- Exhaustive: System is always in exactly one state
- Meaningful: State names reflect business concepts
- Stable: State represents a stable condition, not a transition
Example (Payment):
β
Good States:
- Pending: Waiting for payment authorization
- Authorized: Payment approved but not captured
- Captured: Money received
- Refunded: Money returned to customer
- Failed: Payment processing failed
β Bad States:
- "ProcessingPayment" - This is a transition, not a stable state
- "Data" - Too generic, not meaningfulTransitions
Definition: Rules defining how the system moves from one state to another.
Transition Anatomy:
Current State + Event β Next State [Guard Condition] / ActionExample:
Pending + PaymentReceived β Confirmed [amount >= total] / SendConfirmationEmailGuard Conditions (optional): Boolean conditions that must be true for transition to occur.
Events/Inputs
Definition: External triggers causing state transitions.
Event Types:
- User actions: Button clicks, form submissions
- System events: Timeouts, scheduled tasks, API callbacks
- External events: Webhooks, message queue messages
- Internal events: State entry/exit, timers
Example:
User Events: Submit, Cancel, Approve, Reject
System Events: Timeout, Retry, AutoExpire
External Events: PaymentReceived, InventoryRestockedActions
Definition: Operations executed during transitions or while in a state.
Action Types:
- Entry actions: Execute when entering a state
- Exit actions: Execute when leaving a state
- Transition actions: Execute during state change
- Internal actions: Execute within state without transition
Example:
State: Processing
Entry Action: StartProcessingTimer, LogStateEntry
Exit Action: StopProcessingTimer
Internal Action (on RetryEvent): IncrementRetryCountπ Real-World Applications
1. Order Processing
States: Created β Pending β Confirmed β Shipped β Delivered β Closed
Transitions:
Created + Submit β Pending
Pending + Approve β Confirmed
Confirmed + Ship β Shipped
Shipped + Deliver β Delivered
Delivered + Archive β Closed
Any State + Cancel β Cancelled (if allowed)2. User Authentication
States: Unauthenticated β Authenticating β Authenticated β LoggedOut
Transitions:
Unauthenticated + Login β Authenticating
Authenticating + Success β Authenticated
Authenticating + Failure β Unauthenticated
Authenticated + Logout β LoggedOut
Authenticated + SessionExpired β Unauthenticated3. Document Workflow
States: Draft β Review β Approved β Published β Archived
Transitions:
Draft + Submit β Review
Review + Approve β Approved
Review + Reject β Draft [with comments]
Approved + Publish β Published
Published + Archive β Archived
Any State + Delete β Deleted (if allowed)4. Traffic Light
States: Red β Green β Yellow β Red (cycle)
Transitions:
Red + Timer(30s) β Green
Green + Timer(45s) β Yellow
Yellow + Timer(5s) β Red
Actions:
Red Entry: StopTraffic, AllowPedestrians
Green Entry: AllowTraffic, StopPedestrians
Yellow Entry: WarnTrafficπ FSM Design Best Practices
Do:
- β Name states meaningfully: Use business domain language (not “State1”, “State2”)
- β Keep states minimal: Only create states that represent distinct system behavior
- β Make transitions explicit: Document all valid state changes
- β Use guard conditions: Prevent invalid transitions based on data
- β Define initial state: System must have a clear starting point
- β Handle all events: Every state should handle all possible events (even if just ignoring them)
- β Document state meaning: What does being in this state mean for the system?
Don’t:
- β Mix concerns: Don’t embed complex business logic directly in FSM - use actions
- β Create too many states: Complexity grows quadratically with states
- β Forget error handling: Always have error states and recovery transitions
- β Ignore impossible transitions: Explicitly prevent or handle invalid state changes
- β Use FSM for everything: Simple sequential workflows don’t need FSMs
π§ Implementation Patterns
1. State Pattern (OOP)
// State interface
type OrderState interface {
Confirm(order *Order) error
Ship(order *Order) error
Deliver(order *Order) error
}
// Concrete state
type PendingState struct{}
func (s *PendingState) Confirm(order *Order) error {
order.State = &ConfirmedState{}
return nil
}
func (s *PendingState) Ship(order *Order) error {
return errors.New("cannot ship pending order")
}
// Order with state
type Order struct {
ID string
State OrderState
}2. Enum/Switch Pattern
type OrderStatus int
const (
Pending OrderStatus = iota
Confirmed
Shipped
Delivered
)
func (o *Order) Confirm() error {
switch o.Status {
case Pending:
o.Status = Confirmed
return nil
default:
return errors.New("cannot confirm from current state")
}
}3. State Machine Library
// Using a library (example: github.com/looplab/fsm)
fsm := fsm.NewFSM(
"pending",
fsm.Events{
{Name: "confirm", Src: []string{"pending"}, Dst: "confirmed"},
{Name: "ship", Src: []string{"confirmed"}, Dst: "shipped"},
{Name: "deliver", Src: []string{"shipped"}, Dst: "delivered"},
},
fsm.Callbacks{
"enter_confirmed": func(e *fsm.Event) { sendConfirmationEmail() },
},
)
fsm.Event("confirm") // Transition to confirmedπ‘ When to Use FSM
FSM is Ideal When:
- β System has clearly defined states (order status, user authentication, game state)
- β State-dependent behavior: Actions vary based on current state
- β Explicit transitions: Business rules dictate specific state changes
- β Finite number of states: Doesn’t grow unbounded
- β Complex validation: Enforcing what can happen when
- β Workflow management: Document approval, order processing
FSM is Overkill When:
- β Simple boolean flags suffice (
isActive,isComplete) - β States are infinite or data-driven
- β No state-dependent behavior
- β Linear, sequential flow with no branching
- β Stateless operations
π Getting Started with FSM
Step-by-Step Approach:
- Identify states: List all distinct modes your system can be in
- Define events: What triggers state changes?
- Map transitions: For each state-event pair, what happens?
- Add guard conditions: When should transitions be prevented?
- Define actions: What happens during transitions?
- Draw state diagram: Visualize the FSM
- Implement: Choose implementation pattern (State Pattern, Enum/Switch, Library)
- Test: Verify all transitions and guard conditions
First FSM Checklist:
- Listed all possible states
- Defined initial state
- Identified all events/triggers
- Mapped all valid transitions
- Added guard conditions for conditional transitions
- Defined entry/exit actions for key states
- Created state diagram
- Handled invalid transitions (error cases)
π Related Content
- C4 Model - Use Component diagrams to show FSM within system architecture
- Domain-Driven Design - FSMs often model entity lifecycles in DDD
- System Design Cases - See FSMs in real-world system workflows
π Further Reading
Books:
- Introduction to Automata Theory, Languages, and Computation by Hopcroft & Ullman - Theoretical foundation
- Design Patterns by Gang of Four - State Pattern chapter
- UML Distilled by Martin Fowler - State diagrams in UML
Online Resources:
- State Machine Cat - Draw state machines online
- XState - JavaScript state machine library with visual tooling
- PlantUML State Diagrams - Text-based state diagram tool
Tools:
- PlantUML: Text-based state diagram generation
- Mermaid: Markdown-embeddable state diagrams
- Draw.io: Visual state diagram editor
- Statecharts: Hierarchical state machine notation (David Harel)
Key Takeaway: Finite State Machines bring clarity and rigor to systems with well-defined states and transitions. Use FSMs when state-dependent behavior is critical to business logic, and transitions must be explicit and controlled. They transform complex conditional logic into visual, testable, maintainable state management.