A transition function makes the rules for moving between model states easy to test.

transition function Keep state changes in one helper so each branch explains when the model can advance.

State Transitions

paid
state_transitions.go
Replay: real traced execution (multi-file project)
package main

import "fmt"

const (
	OrderNew = iota
	OrderPaid
	OrderShipped
)

func nextState(current int, paid bool) int {
	if current == OrderNew && paid {
		return OrderPaid
	}
	if current == OrderPaid {
		return OrderShipped
	}
	return current
}

func main() {
	var paid = true
	current := OrderNew
	next := nextState(current, paid)
	done := next == OrderShipped

	fmt.Println("paid=", paid)
	fmt.Println("current=", current)
	fmt.Println("next=", next)
	fmt.Println("done=", done)
}
package main

import "fmt"

const (
	OrderNew = iota
	OrderPaid
	OrderShipped
)

func nextState(current int, paid bool) int {
	if current == OrderNew && paid {
		return OrderPaid
	}
	if current == OrderPaid {
		return OrderShipped
	}
	return current
}

func main() {
	var paid = false
	current := OrderNew
	next := nextState(current, paid)
	done := next == OrderShipped

	fmt.Println("paid=", paid)
	fmt.Println("current=", current)
	fmt.Println("next=", next)
	fmt.Println("done=", done)
}
  1. paid ← true, current ← 0

    21func main() {22  var paid→ true = true //@paid=false23  current→ 0 := OrderNew024  next := nextState(current0, paidtrue)25  done := next == OrderShipped
  2. func nextState(current int, paid bool) int

    11func nextState(current0 int, paidtrue bool) int {12  if current == OrderNew && paid {
  3. if current == OrderNew && paid

    11func nextState(current int, paid bool) int {12  if current0 == OrderNew0 && paidtrue {13    return OrderPaid114  }
  4. next ← 1, done ← false

    23  current := OrderNew24  next→ 1 := nextState(current0, paidtrue)25  done→ false := next1 == OrderShipped22627  fmt.Println("paid=", paidtrue)28  fmt.Println("current=", current0)29  fmt.Println("next=", next1)30  fmt.Println("done=", donefalse)31}
    outputpaid= true
    current= 0
    next= 1
    done= false
  1. paid ← false, current ← 0

    21func main() {22  var paid→ false = false23  current→ 0 := OrderNew024  next := nextState(current0, paidfalse)25  done := next == OrderShipped
  2. func nextState(current int, paid bool) int

    11func nextState(current0 int, paidfalse bool) int {12  if current == OrderNew && paid {13    return OrderPaid14  }15  if current == OrderPaid {16    return OrderShipped17  }18  return current019}
  3. next ← 0, done ← false

    23  current := OrderNew24  next→ 0 := nextState(current0, paidfalse)25  done→ false := next0 == OrderShipped22627  fmt.Println("paid=", paidfalse)28  fmt.Println("current=", current0)29  fmt.Println("next=", next0)30  fmt.Println("done=", donefalse)31}
    outputpaid= false
    current= 0
    next= 0
    done= false