UML State Machine & Communication Diagrams: Object Lifecycles (Part 7)

UML State Machine & Communication Diagrams: Object Lifecycles (Part 7)

Communication diagrams show the same information as sequence diagrams but emphasize object relationships rather than time sequence. They’re particularly useful when the network of collaborating objects is more important than the temporal ordering of interactions.

|1: Place Order| W W –>|2: Create Order| O O –>|3: Check Stock| I I –>|4: Stock Available| O O –>|5: Process Payment| P P –>|6: Payment Success| O O –>|7: Reserve Items| I I –>|8: Items Reserved| O O –>|9: Order Confirmed| W W –>|10: Show Confirmation| C

Complex Object Collaboration

Communication diagrams excel when showing complex networks of object relationships:

flowchart TD
    Controller[OrderController]
    Validator[OrderValidator]
    Service[OrderService]
    Repository[OrderRepository]
    Cache[CacheManager]
    Events[EventPublisher]
    Email[EmailService]
    
    Controller -->|1: validate| Validator
    Validator -->|2: check rules| Service
    Controller -->|3: create order| Service
    Service -->|4: save| Repository
    Service -->|5: cache| Cache
    Service -->|6: publish event| Events
    Events -->|7: send confirmation| Email
    Repository -->|8: order created| Service
    Service -->|9: order result| Controller

Real-World Example: Document Workflow System

Let’s model a document approval system that demonstrates both state machines and communication patterns:

Draft : Create Document Draft –> UnderReview : Submit for Review Draft –> Archived : Delete Draft UnderReview –> Approved : Manager Approval UnderReview –> Rejected : Manager Rejection UnderReview –> Draft : Recall for Edits Rejected –> Draft : Revise Document Rejected –> Archived : Abandon Document Approved –> Published : Publish Document Approved –> Archived : Archive Approved Published –> UnderReview : Request Changes Published –> Archived : Retire Document state UnderReview { [*] –> ManagerReview ManagerReview –> LegalReview : [requires legal] ManagerReview –> TechnicalReview : [requires technical] LegalReview –> Complete TechnicalReview –> Complete Complete –> [*] } Archived –> [*]

Document System Communication

flowchart LR
    Author[Document Author]
    System[Document System]
    Manager[Manager]
    Legal[Legal Team]
    Notification[Notification Service]
    Storage[Document Storage]
    
    Author -->|1: submit document| System
    System -->|2: store document| Storage
    System -->|3: notify manager| Notification
    Notification -->|4: send email| Manager
    Manager -->|5: review document| System
    System -->|6: get document| Storage
    Manager -->|7: approve/reject| System
    System -->|8: update status| Storage
    System -->|9: notify author| Notification
    System -->|10: route to legal| Legal

Event-Driven System Modeling

State machines are perfect for modeling event-driven systems where objects respond to external stimuli:

IoT Device State Machine

stateDiagram-v2
    [*] --> Offline : Device Boot
    
    Offline --> Connecting : Network Available
    Connecting --> Online : Connection Success
    Connecting --> Offline : Connection Failed
    
    Online --> Collecting : Start Data Collection
    Online --> Idle : Stop Collection
    Online --> Offline : Network Lost
    
    Collecting --> Transmitting : Buffer Full
    Collecting --> Idle : Stop Command
    Collecting --> LowPower : Battery Low
    
    Transmitting --> Collecting : Transmission Complete
    Transmitting --> Error : Transmission Failed
    
    Error --> Collecting : Retry Success
    Error --> Offline : Max Retries Exceeded
    
    LowPower --> Collecting : Battery Charged
    LowPower --> Offline : Critical Battery
    
    Idle --> Collecting : Start Command
    Idle --> Offline : Shutdown Command
    
    note right of LowPower : Reduce sampling rate
Disable non-essential features note right of Error : Implement exponential
backoff for retries

Game State Management

Game development heavily relies on state machines for managing game states, player actions, and AI behavior:

stateDiagram-v2
    [*] --> MainMenu : Game Launch
    
    MainMenu --> Loading : Start Game
    MainMenu --> Settings : Configure Options
    MainMenu --> [*] : Exit Game
    
    Settings --> MainMenu : Save Settings
    
    Loading --> Playing : Assets Loaded
    Loading --> Error : Load Failed
    
    Error --> MainMenu : Return to Menu
    
    Playing --> Paused : Pause Game
    Playing --> GameOver : Player Dies
    Playing --> Victory : Level Complete
    Playing --> MainMenu : Quit to Menu
    
    Paused --> Playing : Resume Game
    Paused --> MainMenu : Quit to Menu
    
    GameOver --> Playing : Retry Level
    GameOver --> MainMenu : Return to Menu
    
    Victory --> Loading : Next Level
    Victory --> MainMenu : Return to Menu
    
    state Playing {
        [*] --> Exploring
        
        Exploring --> Combat : Enemy Encounter
        Exploring --> Inventory : Open Inventory
        Exploring --> Dialog : NPC Interaction
        
        Combat --> Exploring : Combat Won
        Combat --> [*] : Player Defeated
        
        Inventory --> Exploring : Close Inventory
        Dialog --> Exploring : End Conversation
    }

Communication Diagrams in Practice

Communication diagrams are particularly useful when you want to understand the overall structure of object collaborations without getting caught up in timing details:

Banking Transaction Network

flowchart TB
    ATM[ATM Machine]
    Card[Customer Card]
    Bank[Bank System]
    Account[Account Service]
    Fraud[Fraud Detection]
    Audit[Audit Logger]
    Network[Network Service]
    
    Card -->|1: Insert Card| ATM
    ATM -->|2: Read Card Data| Card
    ATM -->|3: Connect to Bank| Network
    Network -->|4: Authenticate| Bank
    Bank -->|5: Validate Card| Account
    Bank -->|6: Check Fraud| Fraud
    Account -->|7: Account Valid| Bank
    Fraud -->|8: Transaction Safe| Bank
    Bank -->|9: Approve Transaction| ATM
    ATM -->|10: Dispense Cash| Card
    Bank -->|11: Log Transaction| Audit
    Account -->|12: Update Balance| Bank

Concurrent State Management

Some objects have multiple independent state aspects that can change simultaneously:

stateDiagram-v2
    state MediaPlayer {
        --
        
        state PlaybackState {
            [*] --> Stopped
            Stopped --> Playing : Play
            Playing --> Paused : Pause
            Playing --> Stopped : Stop
            Paused --> Playing : Resume
            Paused --> Stopped : Stop
        }
        
        --
        
        state VolumeState {
            [*] --> Normal
            Normal --> Muted : Mute
            Normal --> Loud : Volume Up
            Muted --> Normal : Unmute
            Loud --> Normal : Volume Down
        }
        
        --
        
        state ConnectionState {
            [*] --> Disconnected
            Disconnected --> Connected : Network Available
            Connected --> Streaming : Start Stream
            Connected --> Disconnected : Network Lost
            Streaming --> Connected : Stop Stream
            Streaming --> Buffering : Slow Network
            Buffering --> Streaming : Network Improved
            Buffering --> Disconnected : Network Lost
        }
    }

State Machine Implementation Patterns

State machines translate naturally to code using several common patterns:

State Pattern Implementation

// State Pattern based on state machine diagram
abstract class OrderState {
    abstract handle(event: string, order: Order): OrderState;
    abstract canTransitionTo(newState: string): boolean;
}

class PendingState extends OrderState {
    handle(event: string, order: Order): OrderState {
        switch(event) {
            case 'PROCESS_PAYMENT':
                return new PaymentProcessingState();
            case 'CANCEL':
                return new CancelledState();
            default:
                throw new Error(`Invalid event ${event} for Pending state`);
        }
    }
    
    canTransitionTo(newState: string): boolean {
        return ['PaymentProcessing', 'Cancelled'].includes(newState);
    }
}

class PaymentProcessingState extends OrderState {
    handle(event: string, order: Order): OrderState {
        switch(event) {
            case 'PAYMENT_SUCCESS':
                return new PaidState();
            case 'PAYMENT_FAILED':
                return new PaymentFailedState();
            case 'CANCEL':
                return new CancelledState();
            default:
                throw new Error(`Invalid event ${event} for PaymentProcessing state`);
        }
    }
}

// Order class uses state pattern
class Order {
    private state: OrderState = new PendingState();
    
    processEvent(event: string): void {
        const newState = this.state.handle(event, this);
        this.transitionTo(newState);
    }
    
    private transitionTo(newState: OrderState): void {
        // Log state change, trigger actions, etc.
        this.state = newState;
    }
}

Best Practices for State and Communication Modeling

State Machine Guidelines

  • Clear State Names: Use descriptive names that reflect the object’s condition
  • Complete Transitions: Ensure all valid state changes are modeled
  • Guard Conditions: Use conditions to prevent invalid transitions
  • Actions and Activities: Document what happens during transitions and while in states

Communication Diagram Guidelines

  • Number Messages: Use sequence numbers to show temporal ordering
  • Focus on Structure: Emphasize object relationships over timing
  • Keep it Simple: Don’t overcrowd with too many objects
  • Show Key Interactions: Include only the most important message flows

Integration with Modern Development

State machines and communication patterns integrate well with contemporary development practices:

React State Management

// React component based on form state machine
const useFormState = () => {
    const [state, setState] = useState('empty');
    const [data, setData] = useState({});
    const [errors, setErrors] = useState([]);
    
    const handleEvent = (event, payload) => {
        switch(state) {
            case 'empty':
                if (event === 'INPUT') {
                    setState('typing');
                    setData(payload);
                }
                break;
                
            case 'typing':
                if (event === 'VALIDATE') {
                    const validationErrors = validateData(payload);
                    if (validationErrors.length === 0) {
                        setState('valid');
                        setErrors([]);
                    } else {
                        setState('invalid');
                        setErrors(validationErrors);
                    }
                }
                break;
                
            case 'valid':
                if (event === 'SUBMIT') {
                    setState('submitting');
                }
                break;
        }
    };
    
    return { state, data, errors, handleEvent };
};

API State Tracking

REST APIs can use state machines to track resource lifecycles:

// API endpoints derived from state machine
PUT /api/orders/{id}/transition
{
  "event": "PROCESS_PAYMENT",
  "data": {
    "paymentMethod": "credit_card",
    "amount": 99.99
  }
}

// Response includes new state
{
  "orderId": "ORD-123",
  "currentState": "payment_processing",
  "allowedTransitions": ["payment_success", "payment_failed", "cancel"],
  "stateData": {
    "paymentAttempts": 1,
    "lastAttempt": "2025-09-06T18:30:00Z"
  }
}

Conclusion: Managing Complexity Through State

State Machine and Communication diagrams provide essential perspectives on system behavior that complement sequence and activity diagrams. State machines help us understand object lifecycles and ensure consistent behavior across state transitions, while Communication diagrams reveal the network structure of object collaborations.

These diagram types are particularly valuable in modern development where systems must handle complex user interactions, manage distributed state, and respond reliably to events. They provide the foundation for implementing robust state management in everything from user interfaces to distributed systems.

In our next post, we’ll explore Deployment and Timing diagrams—focusing on how software maps to hardware infrastructure and how to model precise timing requirements in real-time systems.

State machines are particularly valuable for modeling user interface behavior and form validation:

stateDiagram-v2
    [*] --> Empty : Form Loaded
    
    Empty --> Typing : User Input
    Typing --> Valid : Validation Pass
    Typing --> Invalid : Validation Fail
    Typing --> Empty : Clear Form
    
    Valid --> Submitting : Submit Button
    Valid --> Typing : Continue Editing
    Valid --> Empty : Clear Form
    
    Invalid --> Typing : Fix Errors
    Invalid --> Empty : Clear Form
    
    Submitting --> Success : Server Success
    Submitting --> Error : Server Error
    Submitting --> Valid : Cancel Submit
    
    Success --> Empty : New Form
    Error --> Valid : Retry
    Error --> Empty : Give Up
    
    note right of Invalid : Show error messages
Disable submit button note right of Submitting : Show loading spinner
Disable all inputs note right of Success : Show success message
Enable new form

Communication Diagrams: Alternative Interaction View

Communication diagrams show the same information as sequence diagrams but emphasize object relationships rather than time sequence. They’re particularly useful when the network of collaborating objects is more important than the temporal ordering of interactions.

Communication vs Sequence Diagrams

Here’s the same order processing scenario shown in both formats:

flowchart LR
    C[Customer]
    W[WebApp]
    O[OrderService]
    P[PaymentService]
    I[InventoryService]
    
    C -->|1: Place Order| W
    W -->|2: Create Order| O
    O -->|3: Check Stock| I
    I -->|4: Stock Available| O
    O -->|5: Process Payment| P
    P -->|6: Payment Success| O
    O -->|7: Reserve Items| I
    I -->|8: Items Reserved| O
    O -->|9: Order Confirmed| W
    W -->|10: Show Confirmation| C

Complex Object Collaboration

Communication diagrams excel when showing complex networks of object relationships:

flowchart TD
    Controller[OrderController]
    Validator[OrderValidator]
    Service[OrderService]
    Repository[OrderRepository]
    Cache[CacheManager]
    Events[EventPublisher]
    Email[EmailService]
    
    Controller -->|1: validate| Validator
    Validator -->|2: check rules| Service
    Controller -->|3: create order| Service
    Service -->|4: save| Repository
    Service -->|5: cache| Cache
    Service -->|6: publish event| Events
    Events -->|7: send confirmation| Email
    Repository -->|8: order created| Service
    Service -->|9: order result| Controller

Real-World Example: Document Workflow System

Let’s model a document approval system that demonstrates both state machines and communication patterns:

Document State Machine

stateDiagram-v2
    [*] --> Draft : Create Document
    
    Draft --> UnderReview : Submit for Review
    Draft --> Archived : Delete Draft
    
    UnderReview --> Approved : Manager Approval
    UnderReview --> Rejected : Manager Rejection
    UnderReview --> Draft : Recall for Edits
    
    Rejected --> Draft : Revise Document
    Rejected --> Archived : Abandon Document
    
    Approved --> Published : Publish Document
    Approved --> Archived : Archive Approved
    
    Published --> UnderReview : Request Changes
    Published --> Archived : Retire Document
    
    state UnderReview {
        [*] --> ManagerReview
        ManagerReview --> LegalReview : [requires legal]
        ManagerReview --> TechnicalReview : [requires technical]
        LegalReview --> Complete
        TechnicalReview --> Complete
        Complete --> [*]
    }
    
    Archived --> [*]

Document System Communication

flowchart LR
    Author[Document Author]
    System[Document System]
    Manager[Manager]
    Legal[Legal Team]
    Notification[Notification Service]
    Storage[Document Storage]
    
    Author -->|1: submit document| System
    System -->|2: store document| Storage
    System -->|3: notify manager| Notification
    Notification -->|4: send email| Manager
    Manager -->|5: review document| System
    System -->|6: get document| Storage
    Manager -->|7: approve/reject| System
    System -->|8: update status| Storage
    System -->|9: notify author| Notification
    System -->|10: route to legal| Legal

Event-Driven System Modeling

State machines are perfect for modeling event-driven systems where objects respond to external stimuli:

IoT Device State Machine

stateDiagram-v2
    [*] --> Offline : Device Boot
    
    Offline --> Connecting : Network Available
    Connecting --> Online : Connection Success
    Connecting --> Offline : Connection Failed
    
    Online --> Collecting : Start Data Collection
    Online --> Idle : Stop Collection
    Online --> Offline : Network Lost
    
    Collecting --> Transmitting : Buffer Full
    Collecting --> Idle : Stop Command
    Collecting --> LowPower : Battery Low
    
    Transmitting --> Collecting : Transmission Complete
    Transmitting --> Error : Transmission Failed
    
    Error --> Collecting : Retry Success
    Error --> Offline : Max Retries Exceeded
    
    LowPower --> Collecting : Battery Charged
    LowPower --> Offline : Critical Battery
    
    Idle --> Collecting : Start Command
    Idle --> Offline : Shutdown Command
    
    note right of LowPower : Reduce sampling rate
Disable non-essential features note right of Error : Implement exponential
backoff for retries

Game State Management

Game development heavily relies on state machines for managing game states, player actions, and AI behavior:

stateDiagram-v2
    [*] --> MainMenu : Game Launch
    
    MainMenu --> Loading : Start Game
    MainMenu --> Settings : Configure Options
    MainMenu --> [*] : Exit Game
    
    Settings --> MainMenu : Save Settings
    
    Loading --> Playing : Assets Loaded
    Loading --> Error : Load Failed
    
    Error --> MainMenu : Return to Menu
    
    Playing --> Paused : Pause Game
    Playing --> GameOver : Player Dies
    Playing --> Victory : Level Complete
    Playing --> MainMenu : Quit to Menu
    
    Paused --> Playing : Resume Game
    Paused --> MainMenu : Quit to Menu
    
    GameOver --> Playing : Retry Level
    GameOver --> MainMenu : Return to Menu
    
    Victory --> Loading : Next Level
    Victory --> MainMenu : Return to Menu
    
    state Playing {
        [*] --> Exploring
        
        Exploring --> Combat : Enemy Encounter
        Exploring --> Inventory : Open Inventory
        Exploring --> Dialog : NPC Interaction
        
        Combat --> Exploring : Combat Won
        Combat --> [*] : Player Defeated
        
        Inventory --> Exploring : Close Inventory
        Dialog --> Exploring : End Conversation
    }

Communication Diagrams in Practice

Communication diagrams are particularly useful when you want to understand the overall structure of object collaborations without getting caught up in timing details:

Banking Transaction Network

flowchart TB
    ATM[ATM Machine]
    Card[Customer Card]
    Bank[Bank System]
    Account[Account Service]
    Fraud[Fraud Detection]
    Audit[Audit Logger]
    Network[Network Service]
    
    Card -->|1: Insert Card| ATM
    ATM -->|2: Read Card Data| Card
    ATM -->|3: Connect to Bank| Network
    Network -->|4: Authenticate| Bank
    Bank -->|5: Validate Card| Account
    Bank -->|6: Check Fraud| Fraud
    Account -->|7: Account Valid| Bank
    Fraud -->|8: Transaction Safe| Bank
    Bank -->|9: Approve Transaction| ATM
    ATM -->|10: Dispense Cash| Card
    Bank -->|11: Log Transaction| Audit
    Account -->|12: Update Balance| Bank

Concurrent State Management

Some objects have multiple independent state aspects that can change simultaneously:

stateDiagram-v2
    state MediaPlayer {
        --
        
        state PlaybackState {
            [*] --> Stopped
            Stopped --> Playing : Play
            Playing --> Paused : Pause
            Playing --> Stopped : Stop
            Paused --> Playing : Resume
            Paused --> Stopped : Stop
        }
        
        --
        
        state VolumeState {
            [*] --> Normal
            Normal --> Muted : Mute
            Normal --> Loud : Volume Up
            Muted --> Normal : Unmute
            Loud --> Normal : Volume Down
        }
        
        --
        
        state ConnectionState {
            [*] --> Disconnected
            Disconnected --> Connected : Network Available
            Connected --> Streaming : Start Stream
            Connected --> Disconnected : Network Lost
            Streaming --> Connected : Stop Stream
            Streaming --> Buffering : Slow Network
            Buffering --> Streaming : Network Improved
            Buffering --> Disconnected : Network Lost
        }
    }

State Machine Implementation Patterns

State machines translate naturally to code using several common patterns:

State Pattern Implementation

// State Pattern based on state machine diagram
abstract class OrderState {
    abstract handle(event: string, order: Order): OrderState;
    abstract canTransitionTo(newState: string): boolean;
}

class PendingState extends OrderState {
    handle(event: string, order: Order): OrderState {
        switch(event) {
            case 'PROCESS_PAYMENT':
                return new PaymentProcessingState();
            case 'CANCEL':
                return new CancelledState();
            default:
                throw new Error(`Invalid event ${event} for Pending state`);
        }
    }
    
    canTransitionTo(newState: string): boolean {
        return ['PaymentProcessing', 'Cancelled'].includes(newState);
    }
}

class PaymentProcessingState extends OrderState {
    handle(event: string, order: Order): OrderState {
        switch(event) {
            case 'PAYMENT_SUCCESS':
                return new PaidState();
            case 'PAYMENT_FAILED':
                return new PaymentFailedState();
            case 'CANCEL':
                return new CancelledState();
            default:
                throw new Error(`Invalid event ${event} for PaymentProcessing state`);
        }
    }
}

// Order class uses state pattern
class Order {
    private state: OrderState = new PendingState();
    
    processEvent(event: string): void {
        const newState = this.state.handle(event, this);
        this.transitionTo(newState);
    }
    
    private transitionTo(newState: OrderState): void {
        // Log state change, trigger actions, etc.
        this.state = newState;
    }
}

Best Practices for State and Communication Modeling

State Machine Guidelines

  • Clear State Names: Use descriptive names that reflect the object’s condition
  • Complete Transitions: Ensure all valid state changes are modeled
  • Guard Conditions: Use conditions to prevent invalid transitions
  • Actions and Activities: Document what happens during transitions and while in states

Communication Diagram Guidelines

  • Number Messages: Use sequence numbers to show temporal ordering
  • Focus on Structure: Emphasize object relationships over timing
  • Keep it Simple: Don’t overcrowd with too many objects
  • Show Key Interactions: Include only the most important message flows

Integration with Modern Development

State machines and communication patterns integrate well with contemporary development practices:

React State Management

// React component based on form state machine
const useFormState = () => {
    const [state, setState] = useState('empty');
    const [data, setData] = useState({});
    const [errors, setErrors] = useState([]);
    
    const handleEvent = (event, payload) => {
        switch(state) {
            case 'empty':
                if (event === 'INPUT') {
                    setState('typing');
                    setData(payload);
                }
                break;
                
            case 'typing':
                if (event === 'VALIDATE') {
                    const validationErrors = validateData(payload);
                    if (validationErrors.length === 0) {
                        setState('valid');
                        setErrors([]);
                    } else {
                        setState('invalid');
                        setErrors(validationErrors);
                    }
                }
                break;
                
            case 'valid':
                if (event === 'SUBMIT') {
                    setState('submitting');
                }
                break;
        }
    };
    
    return { state, data, errors, handleEvent };
};

API State Tracking

REST APIs can use state machines to track resource lifecycles:

// API endpoints derived from state machine
PUT /api/orders/{id}/transition
{
  "event": "PROCESS_PAYMENT",
  "data": {
    "paymentMethod": "credit_card",
    "amount": 99.99
  }
}

// Response includes new state
{
  "orderId": "ORD-123",
  "currentState": "payment_processing",
  "allowedTransitions": ["payment_success", "payment_failed", "cancel"],
  "stateData": {
    "paymentAttempts": 1,
    "lastAttempt": "2025-09-06T18:30:00Z"
  }
}

Conclusion: Managing Complexity Through State

State Machine and Communication diagrams provide essential perspectives on system behavior that complement sequence and activity diagrams. State machines help us understand object lifecycles and ensure consistent behavior across state transitions, while Communication diagrams reveal the network structure of object collaborations.

These diagram types are particularly valuable in modern development where systems must handle complex user interactions, manage distributed state, and respond reliably to events. They provide the foundation for implementing robust state management in everything from user interfaces to distributed systems.

In our next post, we’ll explore Deployment and Timing diagrams—focusing on how software maps to hardware infrastructure and how to model precise timing requirements in real-time systems.

State Machine and Communication diagrams provide complementary perspectives on system behavior that go beyond the linear flows of sequence diagrams and activity diagrams. State Machine diagrams model how objects change over their lifetime in response to events, while Communication diagrams offer an alternative view of object interactions that emphasizes relationships over time sequence—both essential for understanding complex system behaviors.

In this seventh part of our UML series, we’ll master object lifecycle modeling, event-driven system design, and alternative approaches to documenting object collaboration that reveal insights missed by other diagram types.

State Machine Diagrams: Modeling Object Lifecycles

State Machine diagrams model how objects respond to events by changing states. They’re particularly valuable for objects with complex lifecycles, event-driven systems, and user interface design where objects must maintain consistent behavior across different states.

Core State Machine Elements

  • States: Conditions or situations during an object’s life
  • Transitions: Changes from one state to another triggered by events
  • Events: Occurrences that trigger transitions
  • Actions: Behaviors executed during transitions

Simple Order State Machine

Let’s start with modeling an e-commerce order lifecycle:

stateDiagram-v2
    [*] --> Pending : Order Created
    
    Pending --> PaymentProcessing : Process Payment
    Pending --> Cancelled : Cancel Order
    
    PaymentProcessing --> Paid : Payment Success
    PaymentProcessing --> PaymentFailed : Payment Declined
    PaymentProcessing --> Cancelled : Cancel During Payment
    
    PaymentFailed --> PaymentProcessing : Retry Payment
    PaymentFailed --> Cancelled : Give Up
    
    Paid --> InFulfillment : Start Fulfillment
    InFulfillment --> Shipped : Package Shipped
    InFulfillment --> Cancelled : Cancel Before Ship
    
    Shipped --> Delivered : Package Delivered
    Shipped --> Lost : Package Lost
    
    Delivered --> Completed : Customer Satisfied
    Delivered --> Returned : Return Requested
    
    Returned --> Refunded : Refund Processed
    Lost --> Refunded : Insurance Claim
    
    Cancelled --> [*]
    Completed --> [*]
    Refunded --> [*]

Advanced State Machine Features

Guard Conditions and Actions

State machines can include conditions that must be met for transitions to occur, and actions that execute during transitions:

stateDiagram-v2
    [*] --> Idle : System Start
    
    Idle --> Processing : Job Received [queue not full]
    Idle --> Rejected : Job Received [queue full] / Log Error
    
    Processing --> Completed : Job Finished [success] / Notify Client
    Processing --> Failed : Job Finished [error] / Log Failure
    Processing --> Paused : Pause Signal [can pause] / Save State
    
    Failed --> Processing : Retry [retry count < 3] / Increment Counter
    Failed --> Abandoned : Retry [retry count >= 3] / Send Alert
    
    Paused --> Processing : Resume Signal / Restore State
    Paused --> Cancelled : Cancel Signal / Cleanup
    
    Completed --> Idle : / Clear Resources
    Abandoned --> Idle : / Clear Resources
    Cancelled --> Idle : / Clear Resources

Composite States and Hierarchical Modeling

Complex objects often have states that contain sub-states, allowing for hierarchical modeling:

stateDiagram-v2
    [*] --> PoweredOff
    
    PoweredOff --> PoweredOn : Power Button
    PoweredOn --> PoweredOff : Power Button
    
    state PoweredOn {
        [*] --> Idle
        
        Idle --> Playing : Play Media
        Idle --> Recording : Start Recording
        
        Playing --> Paused : Pause Button
        Playing --> Idle : Stop Button
        Paused --> Playing : Play Button
        Paused --> Idle : Stop Button
        
        Recording --> Idle : Stop Recording
        
        state Playing {
            [*] --> NormalSpeed
            NormalSpeed --> FastForward : FF Button
            NormalSpeed --> Rewind : Rewind Button
            FastForward --> NormalSpeed : Play Button
            Rewind --> NormalSpeed : Play Button
        }
    }

User Interface State Management

State machines are particularly valuable for modeling user interface behavior and form validation:

stateDiagram-v2
    [*] --> Empty : Form Loaded
    
    Empty --> Typing : User Input
    Typing --> Valid : Validation Pass
    Typing --> Invalid : Validation Fail
    Typing --> Empty : Clear Form
    
    Valid --> Submitting : Submit Button
    Valid --> Typing : Continue Editing
    Valid --> Empty : Clear Form
    
    Invalid --> Typing : Fix Errors
    Invalid --> Empty : Clear Form
    
    Submitting --> Success : Server Success
    Submitting --> Error : Server Error
    Submitting --> Valid : Cancel Submit
    
    Success --> Empty : New Form
    Error --> Valid : Retry
    Error --> Empty : Give Up
    
    note right of Invalid : Show error messages
Disable submit button note right of Submitting : Show loading spinner
Disable all inputs note right of Success : Show success message
Enable new form

Communication Diagrams: Alternative Interaction View

Communication diagrams show the same information as sequence diagrams but emphasize object relationships rather than time sequence. They’re particularly useful when the network of collaborating objects is more important than the temporal ordering of interactions.

Communication vs Sequence Diagrams

Here’s the same order processing scenario shown in both formats:

flowchart LR
    C[Customer]
    W[WebApp]
    O[OrderService]
    P[PaymentService]
    I[InventoryService]
    
    C -->|1: Place Order| W
    W -->|2: Create Order| O
    O -->|3: Check Stock| I
    I -->|4: Stock Available| O
    O -->|5: Process Payment| P
    P -->|6: Payment Success| O
    O -->|7: Reserve Items| I
    I -->|8: Items Reserved| O
    O -->|9: Order Confirmed| W
    W -->|10: Show Confirmation| C

Complex Object Collaboration

Communication diagrams excel when showing complex networks of object relationships:

flowchart TD
    Controller[OrderController]
    Validator[OrderValidator]
    Service[OrderService]
    Repository[OrderRepository]
    Cache[CacheManager]
    Events[EventPublisher]
    Email[EmailService]
    
    Controller -->|1: validate| Validator
    Validator -->|2: check rules| Service
    Controller -->|3: create order| Service
    Service -->|4: save| Repository
    Service -->|5: cache| Cache
    Service -->|6: publish event| Events
    Events -->|7: send confirmation| Email
    Repository -->|8: order created| Service
    Service -->|9: order result| Controller

Real-World Example: Document Workflow System

Let’s model a document approval system that demonstrates both state machines and communication patterns:

Document State Machine

stateDiagram-v2
    [*] --> Draft : Create Document
    
    Draft --> UnderReview : Submit for Review
    Draft --> Archived : Delete Draft
    
    UnderReview --> Approved : Manager Approval
    UnderReview --> Rejected : Manager Rejection
    UnderReview --> Draft : Recall for Edits
    
    Rejected --> Draft : Revise Document
    Rejected --> Archived : Abandon Document
    
    Approved --> Published : Publish Document
    Approved --> Archived : Archive Approved
    
    Published --> UnderReview : Request Changes
    Published --> Archived : Retire Document
    
    state UnderReview {
        [*] --> ManagerReview
        ManagerReview --> LegalReview : [requires legal]
        ManagerReview --> TechnicalReview : [requires technical]
        LegalReview --> Complete
        TechnicalReview --> Complete
        Complete --> [*]
    }
    
    Archived --> [*]

Document System Communication

flowchart LR
    Author[Document Author]
    System[Document System]
    Manager[Manager]
    Legal[Legal Team]
    Notification[Notification Service]
    Storage[Document Storage]
    
    Author -->|1: submit document| System
    System -->|2: store document| Storage
    System -->|3: notify manager| Notification
    Notification -->|4: send email| Manager
    Manager -->|5: review document| System
    System -->|6: get document| Storage
    Manager -->|7: approve/reject| System
    System -->|8: update status| Storage
    System -->|9: notify author| Notification
    System -->|10: route to legal| Legal

Event-Driven System Modeling

State machines are perfect for modeling event-driven systems where objects respond to external stimuli:

IoT Device State Machine

stateDiagram-v2
    [*] --> Offline : Device Boot
    
    Offline --> Connecting : Network Available
    Connecting --> Online : Connection Success
    Connecting --> Offline : Connection Failed
    
    Online --> Collecting : Start Data Collection
    Online --> Idle : Stop Collection
    Online --> Offline : Network Lost
    
    Collecting --> Transmitting : Buffer Full
    Collecting --> Idle : Stop Command
    Collecting --> LowPower : Battery Low
    
    Transmitting --> Collecting : Transmission Complete
    Transmitting --> Error : Transmission Failed
    
    Error --> Collecting : Retry Success
    Error --> Offline : Max Retries Exceeded
    
    LowPower --> Collecting : Battery Charged
    LowPower --> Offline : Critical Battery
    
    Idle --> Collecting : Start Command
    Idle --> Offline : Shutdown Command
    
    note right of LowPower : Reduce sampling rate
Disable non-essential features note right of Error : Implement exponential
backoff for retries

Game State Management

Game development heavily relies on state machines for managing game states, player actions, and AI behavior:

stateDiagram-v2
    [*] --> MainMenu : Game Launch
    
    MainMenu --> Loading : Start Game
    MainMenu --> Settings : Configure Options
    MainMenu --> [*] : Exit Game
    
    Settings --> MainMenu : Save Settings
    
    Loading --> Playing : Assets Loaded
    Loading --> Error : Load Failed
    
    Error --> MainMenu : Return to Menu
    
    Playing --> Paused : Pause Game
    Playing --> GameOver : Player Dies
    Playing --> Victory : Level Complete
    Playing --> MainMenu : Quit to Menu
    
    Paused --> Playing : Resume Game
    Paused --> MainMenu : Quit to Menu
    
    GameOver --> Playing : Retry Level
    GameOver --> MainMenu : Return to Menu
    
    Victory --> Loading : Next Level
    Victory --> MainMenu : Return to Menu
    
    state Playing {
        [*] --> Exploring
        
        Exploring --> Combat : Enemy Encounter
        Exploring --> Inventory : Open Inventory
        Exploring --> Dialog : NPC Interaction
        
        Combat --> Exploring : Combat Won
        Combat --> [*] : Player Defeated
        
        Inventory --> Exploring : Close Inventory
        Dialog --> Exploring : End Conversation
    }

Communication Diagrams in Practice

Communication diagrams are particularly useful when you want to understand the overall structure of object collaborations without getting caught up in timing details:

Banking Transaction Network

flowchart TB
    ATM[ATM Machine]
    Card[Customer Card]
    Bank[Bank System]
    Account[Account Service]
    Fraud[Fraud Detection]
    Audit[Audit Logger]
    Network[Network Service]
    
    Card -->|1: Insert Card| ATM
    ATM -->|2: Read Card Data| Card
    ATM -->|3: Connect to Bank| Network
    Network -->|4: Authenticate| Bank
    Bank -->|5: Validate Card| Account
    Bank -->|6: Check Fraud| Fraud
    Account -->|7: Account Valid| Bank
    Fraud -->|8: Transaction Safe| Bank
    Bank -->|9: Approve Transaction| ATM
    ATM -->|10: Dispense Cash| Card
    Bank -->|11: Log Transaction| Audit
    Account -->|12: Update Balance| Bank

Concurrent State Management

Some objects have multiple independent state aspects that can change simultaneously:

stateDiagram-v2
    state MediaPlayer {
        --
        
        state PlaybackState {
            [*] --> Stopped
            Stopped --> Playing : Play
            Playing --> Paused : Pause
            Playing --> Stopped : Stop
            Paused --> Playing : Resume
            Paused --> Stopped : Stop
        }
        
        --
        
        state VolumeState {
            [*] --> Normal
            Normal --> Muted : Mute
            Normal --> Loud : Volume Up
            Muted --> Normal : Unmute
            Loud --> Normal : Volume Down
        }
        
        --
        
        state ConnectionState {
            [*] --> Disconnected
            Disconnected --> Connected : Network Available
            Connected --> Streaming : Start Stream
            Connected --> Disconnected : Network Lost
            Streaming --> Connected : Stop Stream
            Streaming --> Buffering : Slow Network
            Buffering --> Streaming : Network Improved
            Buffering --> Disconnected : Network Lost
        }
    }

State Machine Implementation Patterns

State machines translate naturally to code using several common patterns:

State Pattern Implementation

// State Pattern based on state machine diagram
abstract class OrderState {
    abstract handle(event: string, order: Order): OrderState;
    abstract canTransitionTo(newState: string): boolean;
}

class PendingState extends OrderState {
    handle(event: string, order: Order): OrderState {
        switch(event) {
            case 'PROCESS_PAYMENT':
                return new PaymentProcessingState();
            case 'CANCEL':
                return new CancelledState();
            default:
                throw new Error(`Invalid event ${event} for Pending state`);
        }
    }
    
    canTransitionTo(newState: string): boolean {
        return ['PaymentProcessing', 'Cancelled'].includes(newState);
    }
}

class PaymentProcessingState extends OrderState {
    handle(event: string, order: Order): OrderState {
        switch(event) {
            case 'PAYMENT_SUCCESS':
                return new PaidState();
            case 'PAYMENT_FAILED':
                return new PaymentFailedState();
            case 'CANCEL':
                return new CancelledState();
            default:
                throw new Error(`Invalid event ${event} for PaymentProcessing state`);
        }
    }
}

// Order class uses state pattern
class Order {
    private state: OrderState = new PendingState();
    
    processEvent(event: string): void {
        const newState = this.state.handle(event, this);
        this.transitionTo(newState);
    }
    
    private transitionTo(newState: OrderState): void {
        // Log state change, trigger actions, etc.
        this.state = newState;
    }
}

Best Practices for State and Communication Modeling

State Machine Guidelines

  • Clear State Names: Use descriptive names that reflect the object’s condition
  • Complete Transitions: Ensure all valid state changes are modeled
  • Guard Conditions: Use conditions to prevent invalid transitions
  • Actions and Activities: Document what happens during transitions and while in states

Communication Diagram Guidelines

  • Number Messages: Use sequence numbers to show temporal ordering
  • Focus on Structure: Emphasize object relationships over timing
  • Keep it Simple: Don’t overcrowd with too many objects
  • Show Key Interactions: Include only the most important message flows

Integration with Modern Development

State machines and communication patterns integrate well with contemporary development practices:

React State Management

// React component based on form state machine
const useFormState = () => {
    const [state, setState] = useState('empty');
    const [data, setData] = useState({});
    const [errors, setErrors] = useState([]);
    
    const handleEvent = (event, payload) => {
        switch(state) {
            case 'empty':
                if (event === 'INPUT') {
                    setState('typing');
                    setData(payload);
                }
                break;
                
            case 'typing':
                if (event === 'VALIDATE') {
                    const validationErrors = validateData(payload);
                    if (validationErrors.length === 0) {
                        setState('valid');
                        setErrors([]);
                    } else {
                        setState('invalid');
                        setErrors(validationErrors);
                    }
                }
                break;
                
            case 'valid':
                if (event === 'SUBMIT') {
                    setState('submitting');
                }
                break;
        }
    };
    
    return { state, data, errors, handleEvent };
};

API State Tracking

REST APIs can use state machines to track resource lifecycles:

// API endpoints derived from state machine
PUT /api/orders/{id}/transition
{
  "event": "PROCESS_PAYMENT",
  "data": {
    "paymentMethod": "credit_card",
    "amount": 99.99
  }
}

// Response includes new state
{
  "orderId": "ORD-123",
  "currentState": "payment_processing",
  "allowedTransitions": ["payment_success", "payment_failed", "cancel"],
  "stateData": {
    "paymentAttempts": 1,
    "lastAttempt": "2025-09-06T18:30:00Z"
  }
}

Conclusion: Managing Complexity Through State

State Machine and Communication diagrams provide essential perspectives on system behavior that complement sequence and activity diagrams. State machines help us understand object lifecycles and ensure consistent behavior across state transitions, while Communication diagrams reveal the network structure of object collaborations.

These diagram types are particularly valuable in modern development where systems must handle complex user interactions, manage distributed state, and respond reliably to events. They provide the foundation for implementing robust state management in everything from user interfaces to distributed systems.

In our next post, we’ll explore Deployment and Timing diagrams—focusing on how software maps to hardware infrastructure and how to model precise timing requirements in real-time systems.

Written by:

339 Posts

View All Posts
Follow Me :

You May Have Missed