artima.com

Part I. Objects
People-Oriented API Design
Guideline 3. Understand the kinship between objects and state machines
by Bill Venners

<<  Page 7 of 20  >>

A State Machine Object

The behavior of the simple stamp dispenser, described previously in both human-language and state machine terms, is exhibited by instances of the StampDispenser class shown in Listing 3-1.

Listing 3-1. Class StampDispenser

package com.artima.examples.stampdispenser.ex4;

import java.util.Set;
import java.util.Iterator;
import java.util.HashSet;

/**
* A stamp dispenser that accepts nickels and dimes and dispenses twenty cent
* stamps.
*
* @author Bill Venners
*/
public class StampDispenser {

    private final static int STAMP_VALUE = 20;
    private int balance;

    /**
    * Constructs a new stamp dispenser with a starting balance of zero.
    */
    public StampDispenser() {
    }

    /**
    * Add either 5 or 10 cents to the stamp dispenser. If the amount added
    * causes the balance to become or exceed 20 cents, the price of a stamp,
    * the stamp will be automatically dispensed. If the stamp is dispensed,
    * the amount of the balance after the stamp is dispensed is returned to
    * the client.
    *
    * @throws IllegalArgumentException if passed <code>amount</code> doesn't
    *    equal either 5 or 10
    */
    public synchronized void add(int amount) {

        if ((amount != 5) && (amount != 10)) {
            throw new IllegalArgumentException();
        }

        balance += amount;

        if (balance >= STAMP_VALUE) {

            // Dispense a stamp and return any change
            // balance - STAMP_VALUE is amount in excess of twenty cents
            // (the stamp price) to return as change. After dispensing the
            // stamp and returning any change, the new balance will be zero.
            System.out.print("Dispense stamp");
            int toReturn = balance - STAMP_VALUE;
            if (toReturn > 0) {
                System.out.println(", return " + toReturn + " cents.");
            }
            else {
                System.out.println(".");
            }
            balance = 0;
        }
    }

    /**
    * Returns coins. If the balance is zero, no action is performed.
    */
    public synchronized void returnCoins() {

        // Make sure balance is greater than zero, because no event should
        // be fired if the coin return lever is pressed when the stamp
        // dispenser has a zero balance
        if (balance > 0) {

            // Return the entire balance to the client
            System.out.println("Return " + balance + " cents.");
            balance = 0;
        }
    }
}

Class StampDispenser has one private instance variable, balance, which maintains the state of the object. Like the stamp dispenser state machine, StampDispenser objects can be in one of four possible states. The four states of the state machine correspond to value of balance in this way:

The StampDispenser class has one public no-arg constructor that ensures all instances begin life with an initial balance of zero. (Because the constructor contains no code, it leaves balance at its default initial value of zero.) A zero balance corresponds to the HAS_0 state, the initial starting state of the stamp dispenser state machine.

The interface of class StampDispenser includes two methods, add and returnCoins. Given a variable stampDispenser that is a reference to a StampDispenser object, invoking the add and returnCoins methods corresponds to sending messages to the state machine in this way:

<<  Page 7 of 20  >>

People-Oriented API Design | Contents | Book List | Print | Email | First Page | Previous | Next

Sponsored Links
Download Artima SuiteRunner Now - It's FREE!

Last Updated: Sunday, May 11, 2003
Copyright © 1996-2003 Artima Software, Inc. All Rights Reserved.
URL: http://www.artima.com/objectdesign/object7.html
Artima.com is created by Bill Venners