Vending Machine
Atomic purchase and credit ownership
A sale transfers ownership of credit and decrements one stock count together. Validate the selected product, stock, and payment before changing any of them. Refunding transfers the entire credit once and resets the customer's session.
type Money int
price, credit := Money(125), Money(200)
fmt.Println(credit-price) // integer minor unitsInventory and balance form a useful conservation model: inserted money equals consumed price plus refunded change plus remaining credit. A lookup failure must not swallow the customer's credit. Separate product records prevent one purchase from modifying another item's stock. Distinguish a missing code from a known sold-out product using errors.
Go models this service with a struct and pointer-receiver methods. Constructor functions return a pointer; validation failures return errors rather than panicking. Scalars in snapshot structs are copied by value. Maps, slices, and optional pointers still require detached copies when crossing the service boundary. Go maps do not have key iteration order; use ordered slices for ranked results. There are no threads, persistence, wall-clock reads, or external side effects in this exercise.
Put it into practice
Implement the exercise in a full-screen workspace, then run its tests.