Modelling parcel delivery. The happy path is straightforward:
Accepted → InTransit → OutForDelivery → Delivered
The problem is that a parcel can be returned from any of those states, and the reason
differs by state. Drawing a transition from every state to Returned gives me a diagram that
is unreadable.
Is there a tidier way, or is the mess telling me something about the model?
The mess is telling you something, but it is a mild something.
A transition from every state to one target is what a composite state is for. Wrap
Accepted, InTransit and OutForDelivery in an enclosing InProgress state and draw a
single return transition from the composite. Anything inside inherits it.
That also gives you a natural place to hang the shared entry and exit behaviour, which you
will want eventually.
The reason differing by state is a separate concern and does not belong in the transition —
put it on the Returned state as an attribute, set by the action on the transition.
Composite state. Of course. I had read about them and never had a reason to reach for one. Diagram went from 14 transitions to 6.
Worth noting for anyone finding this later: if you need the previous state after the return, store it explicitly. Reconstructing it from history afterwards is miserable.