In a UML state machine, when does behaviour belong on a state's entry action rather than on each incoming transition?
answer
- Where the same work keeps repeating
- One arc's work versus every arrival
- Entry, exit and do run at different moments
- Exit, then effect, then entry
- A self-transition re-fires exit and entry
basics
~20 sBehaviour belongs on the entry action whenever every way into the state must run it. A transition effect covers one path only, so work duplicated across several incoming arcs is exactly what an entry action replaces.
solid answer
~40 sPut behaviour on the **entry action** when it must happen no matter which arc brought the object in — starting a timer, publishing a notification, taking a lock. That makes it an invariant of the state rather than a habit of the arcs, so an arc added later cannot silently forget it. Put behaviour on a **transition effect** when it depends on *how* you arrived, such as recording a rejection reason on the one arc that comes back from review. The **exit action** is the mirror of entry and runs on every departure, which is where you release what entry took. A **do activity** models ongoing, interruptible work while the object waits. The ordering is fixed: source exit action, then transition effect, then target entry action.
code
pseudocode · 8 linesstate QUOTE_PENDING
entry / startResponseTimer
do / pollCarrierResponses
exit / stopResponseTimer
internal: operatorNoteAdded / appendNote
carrierQuoted [quoteWithinBudget] / recordQuote -> QUOTED
timerExpired -> EXPIREDgo deeper
Know that a state box can carry entry and exit behaviour and that a do activity runs while the object waits. Recognise the entry, exit and do keywords when you see them written inside a state.
Be able to recite the ordering — source exit, transition effect, target entry — and justify moving work duplicated across four incoming arcs onto a single entry action.
Expect to be pressed on resources: what a self-transition does to a handle the entry action allocated, and what becomes of a half-finished do activity when an event pulls the object out.
Frame the choice as an invariant the state guarantees regardless of the path in, so that a future author adding a fifth incoming arc cannot silently break the model.
## Four places behaviour can live In a UML state machine, executable behaviour attaches in exactly four places, and choosing between them is most of the craft of drawing one well. | Where | Written as | Runs when | Covers | Interruptible | | --- | --- | --- | --- | --- | | Entry action | `entry / behaviour` inside the state | every time the state is entered, from any direction | all incoming arcs | no | | Exit action | `exit / behaviour` inside the state | every time the state is left, in any direction | all outgoing arcs | no | | Do activity | `do / behaviour` inside the state | while the object waits in the state | that state only | yes | | Transition effect | `/ behaviour` on one arc | when that specific arc is taken | one arc | no | ## The ordering rule When an event fires a transition, the order is always: **source exit action, then transition effect, then target entry action.** Nothing else interleaves, because the machine processes one event to completion before dispatching the next. With nesting, exit actions run innermost outward and entry actions run outermost inward, so leaving a substate inside a composite state runs the substate's exit action before the composite's. ## Why entry usually beats duplicating an effect The useful framing is an invariant: **anything that must be true of the object while it is in a state should be established by the state itself, not by whoever drew the arcs.** - If four arcs enter `Quote Pending` and every one of them must start the carrier response timer, the timer belongs on entry. When a fifth arc is added a year later by someone who never read the original diagram, it cannot forget. - If the work depends on the path — recording *why* a booking came back from review — it belongs on that one arc's effect, because it is not true of every entry. A short rule of thumb: 1. Same work on every arrival → entry action. 2. Same cleanup on every departure → exit action. 3. Work that differs by which arc was taken → transition effect. 4. Ongoing work performed while waiting → do activity. 5. Work that must finish before the object counts as settled → entry action, never a do activity. ## Do activities are interruptible by definition A do activity models continuing work: polling for responses, monitoring a sensor, playing media. If an event fires a transition out of the state, the do activity is **aborted** and the exit action runs. Anything that must complete therefore cannot be a do activity. When the requirement really is *when this finishes, move on*, give the state the do activity and draw a **completion transition** — an arc with no trigger — which fires precisely when the activity ends. ## Self-transition versus internal transition This is the sharp edge of the topic, because the two look almost identical on a diagram and behave differently. | | Self-transition | Internal transition | | --- | --- | --- | | Notation | an arc leaving the state and returning to it | a line inside the state box: `event / behaviour` | | Exit action | re-runs | does not run | | Entry action | re-runs | does not run | | Do activity | aborted and restarted | left running untouched | | Use it for | a genuine restart of the state | handling an event without disturbing the state | If the entry action allocates something and the exit action releases it, a self-transition churns that resource on every occurrence. That is usually not what the author meant. ## A worked example On a freight-booking portal, the state `Quote Pending` carries `entry / startResponseTimer`, `do / pollCarrierResponses` and `exit / stopResponseTimer`, and it handles operator notes as an internal transition, `operatorNoteAdded / appendNote`. Operators annotate roughly one booking in seven. Modelling that annotation as a self-transition would have stopped and restarted the response timer each time — and since the carrier response window on that portal is 36 hours, a restarted timer would silently extend the window and hide late carriers from the escalation report. The internal transition is not a stylistic preference there; it is the difference between a correct and an incorrect model. ## Common mistakes - Putting cleanup only on the outgoing arcs the author happened to draw first, so a later arc leaks. - Assuming a do activity always runs to completion before any event is handled. - Believing a self-transition and an internal transition are two spellings of the same thing. - Hoisting path-specific work onto the entry action, so every arrival pays for one arc's needs. - Getting the order wrong and expecting the target's entry action to run before the transition's own effect.
- Does a self-transition on a UML state re-run that state's entry and exit actions?Yes. A self-transition genuinely leaves the state and re-enters it, so the exit action runs, then the transition effect, then the entry action, and any do activity is aborted and restarted. When you want the effect without that churn, declare an internal transition instead: it handles the event inside the state and re-runs neither action. The difference matters most when entry allocates something exit releases.
- What happens to a do activity when an event moves the object out of the state before it finishes?The do activity is aborted, and the exit action then runs. A do activity is interruptible by definition — it models ongoing work performed while the object waits, not a step that must complete. Work that must complete belongs in the entry action, in a transition effect, or in a substate whose completion transition fires only once the work is genuinely done.
saying these in an interview costs you the question
- Puts cleanup only on the outgoing arcs drawn first
- Thinks a do activity always finishes before any event is handled
- Believes a self-transition and an internal transition behave identically
- Uses the entry action for work only one incoming arc needs
- Expects the target's entry action to run before the transition effect