Java Omnibus
OOAD & Architecture / UML / UML State Machine Diagram for Domain State
UML Java Order Management
UML

State machine diagrams are strongest when a domain concept lives through meaningful lifecycle transitions.

Some design problems are really state problems. Orders move from draft to paid to shipped to completed. Shipments move from created to packed to dispatched to delivered. State machine diagrams help clarify which transitions are legal, which events trigger them, and where the domain must defend invariants.

Why This Topic Matters

Why it matters in real Java systems

Java systems often hide lifecycle complexity inside scattered conditionals. A state machine view pulls that complexity into one place, making state rules easier to reason about and implement correctly.

Core Explanation

The design question this UML view answers

State machine diagrams help model lifecycles, not just conditions. They answer questions like which states exist, which transitions are allowed, and what events or guards govern those transitions.

For Java developers, they are especially useful in domains where incorrect transitions are costly. Orders, payments, shipments, subscriptions, and workflow tasks often benefit from explicit lifecycle thinking.

A state machine can also improve the code directly by revealing when an enum plus a few scattered if statements is no longer enough to express the rules safely.

Concept Breakdown

Key ideas to hold onto

Concept

Stateful concepts only

Use state diagrams when lifecycle matters. Not every type needs one.

Concept

Transitions are rules

A state change is often a business rule, not just a field mutation.

Concept

Excellent for domain invariants

State machines make illegal transitions and missing states much easier to spot.

Java Example

Java example in the Order Management domain

Java example: shipment lifecycle guarded in code
package org.javaomnibus.ecommerce.uml;

public final class Shipment {
    private ShipmentStatus status = ShipmentStatus.CREATED;

    public void pack() {
        require(ShipmentStatus.CREATED);
        status = ShipmentStatus.PACKED;
    }

    public void dispatch() {
        require(ShipmentStatus.PACKED);
        status = ShipmentStatus.DISPATCHED;
    }

    public void deliver() {
        require(ShipmentStatus.DISPATCHED);
        status = ShipmentStatus.DELIVERED;
    }

    private void require(ShipmentStatus expected) {
        if (status != expected) {
            throw new IllegalStateException("Illegal transition from " + status);
        }
    }
}

enum ShipmentStatus {
    CREATED, PACKED, DISPATCHED, DELIVERED
}
Code Walkthrough

Step by step

  1. A state machine diagram would show the legal progression from CREATED to DELIVERED.
  2. That gives the team a shared lifecycle model before or alongside the code.
  3. The code then implements the same transitions with explicit guards.
  4. This helps keep state rules centralized and explainable.
Real-World Usage

Where this UML view helps in practice

  • Order, shipment, and payment lifecycle modeling
  • Refactoring scattered transition rules into a coherent model
  • Documenting domain invariants for business-critical workflows
Trade-Offs

When not to overuse it

State diagrams add the most value when lifecycle complexity is real. For simple objects with no meaningful state transitions, they are unnecessary overhead.

Common Mistakes

Frequent mistakes to watch for

  • Drawing state diagrams for concepts that are not meaningfully stateful
  • Ignoring guard conditions and only listing state names
  • Letting the implementation drift away from the documented lifecycle
  • Using a sequence or class diagram when the real issue is transition legality
Related Pages

Related concepts


What To Read Next