The ATM, a system best understood as a conversation
Published . By the DiagramDesk team.
Most classic systems are about data: books, orders, patients. The cash machine is about an exchange of messages between three parties, and it holds very little data of its own. That is why this page starts with the sequence diagram, and why the ER model at the end is the smallest in the series.
The withdrawalUse casesClassesDataData flowMistakes
A withdrawal, message by message
Three lifelines are enough: the customer, the machine and the bank's system. The machine never decides on its own whether a PIN is right or whether the account can pay. In this model it asks, and the bank answers, which is what lets a rule such as "three wrong PINs and the card is kept" hold across every machine rather than being reset by walking to the next one. The three-try limit is this example's assumption; banks set their own.
Three details in that diagram carry marks. The PIN tries are one loop frame with a condition, not three copies of the same three messages. The two outcomes, card kept or cash paid, sit in one alt frame with a guard on each half. And the card comes back before the cash does.
That last one is a design decision with research behind it. Byrne and Bovair, writing in Cognitive Science in 1997, named the mistake a "postcompletion error", and their typical example is "leaving one's card in the automatic teller after withdrawing cash": a step left over once the main goal is met. Ordering the messages so the cash comes last removes the leftover step, and a sequence diagram is where that ordering is written down. The final message, telling the bank the cash was taken, is there for the case where it is not: the notes jam or are never collected, and the debit has to be reversed.
Use cases: one identification step, shared
Every customer use case starts by identifying the customer with a card and a PIN, so it is drawn once, as Identify the customer, and «include»d three times. Keep the card extends that step: it happens only on the third refusal. The bank's system is attached to the identification step because that is where the machine calls on it; attaching it to every use case would say the same thing three more times.
The cash operator is easy to forget, and a model without one has a machine that never runs out of money. Refilling the cash and starting or stopping the machine are real goals for a real person, and they are what feed the reconciliation further down.
Classes: hardware, sessions and a family of transactions
The class diagram falls into three layers. The machine is composed of its devices (a card reader and a cash dispenser are drawn here; a keypad, screen and printer would join them the same way). A session lasts from card in to card out and counts the PIN attempts. And a session performs transactions, of which there are several kinds that differ only in what run() does.
Transaction is marked abstract and its run() carries an asterisk, Mermaid's mark for an abstract method, so no one can create a plain Transaction, only a Withdrawal, a Balance enquiry or a PIN change. A new kind of transaction then means a new subclass, not another branch in an if-statement. Bank link is an interface: the session depends on something that can verify and authorise, not on how the bank's network actually does it, which is also what makes the session testable without a bank.
What the machine itself keeps
An ER model for an ATM is mostly the bank's data seen from one machine, plus a little of the machine's own. Accounts and cards belong to the bank. The machine's contribution is its journal of transactions and the state of its cassettes: how many notes of which denomination are left in each slot.
The ATM transaction records every attempt, including refused ones, with its outcome, because the journal is what gets checked when a customer says the machine took money and gave nothing. The cassette's key is the machine plus the slot number, since slot 2 means nothing without knowing which machine it is in. That makes ATM to Cassette the one identifying relationship, drawn with a solid line; every other line is dashed, because Card, ATM transaction and Refill each have a key of their own.
Data flow: where the numbers must agree
The level 1 DFD earns its place with process 3.0. Every payout writes a journal entry and reduces a cassette's count, and at the end of the day the operator's count of the notes left, the journal and the cassettes' own counts have to agree. That reconciliation is invisible in the use cases and the sequence, and it is the kind of thing a DFD is for.
Mistakes to avoid
- A balance column on the ATM, or an Account table the machine owns. The machine asks; the bank knows.
- Identification repeated inside every use case instead of one «include»d step.
- The PIN attempts drawn three times in the sequence diagram rather than as a loop with a limit.
- One Transaction class with a "type" field and every behaviour switching on it.
- Only the happy path. A refused PIN, a refused withdrawal and a jam each need somewhere to go.
- A line straight from the customer to the bank. In this system the customer only ever talks to the machine.
If your brief adds deposits, add a deposit use case and a cassette for accepted notes; the rest stands. If it asks for a state diagram, the session is the natural subject: waiting for a card, waiting for a PIN, choosing a transaction, and ending.
Keep going
- The banking system, where the accounts behind the machine live
- All the worked systems
- Draw the session as a state diagram