0

I am creating a Java Client to print messages with a small state-machine at the heart of my main class. This client polls a JMS queue and decides if it needs to print a message from a queue or needs to send a message back with JMS.

I was wondering if you Java gurus would share your state-machine advise for this example.

  • I want to keep my state machine in the main class, but want to move all other methods to other classes.
  • Should I keep track of my objects (config, message) as static fields?
  • Is this a good idea?

This is What I got.

State Diagram:

Final State Machine

Main Class:

public class StateMachine {

private static State state;
private static Properties config;
private static Message message;

public static void main(String[] args) throws Exception {

    // Finite State Machine
    state = State.START;
    while (state != State.STOP) {
        switch (state) {
            case START:
                start();
                break;
            case INITIALIZE:
                initialize();
                break;
            case CONFIG:
                config();
                break;
            case POLLING:
                polling();
                break;
            case PUSH:
                push();
                break;
            case MESSAGE:
                message();
                break;
            case PRINT:
                print();
                break;
            case STOP:
                polling();
                break;
            default:
                stop();
                break;
        }
    }
    System.exit(0);
}

private static void start() {
    // The Client is started: move to initialization phase.
    state = State.INITIALIZE;
}

private static void initialize() {
    // Currently nothing - Go directory to configuration
    state = State.CONFIG;
}

private static void config() {
    // Get the configuration
    config = PropertyManager.readConfiguration();

    String task = config.getProperty("task");
    if (task.equals("polling")) {
        state = State.POLLING;
    } else {
        state = State.PUSH;
    }
}

private static void polling() {
    // Start polling until a message arrives
    try {
        ...
        //Implementation that polls a JMQ queue
        ...
        //Break when message arrives
        while (true) {
            message = consumer.receiveNoWait();
            break;
        }
        session.close();
        connection.close();
    } catch (Exception ex) {
        LOGGER.error(" - {}", ex.toString());
    }
    state = State.MESSAGE;
}

private static void push() {
    // Push a message to the queue
    ...
    // Start polling again
    state = State.POLLING;
}

private static void message() {
    // Decides what to do after a message is arrived
    ....
    // Currenty, print all messages
    state = State.PRINT;
}

private static void print() {
    // Print the message
    if (message instanceof TextMessage) {
        ... print ...
    }
    // Move back to polling after a print.
    state = State.POLLING;
}

private static void stop() {
    // Go to the STOP state.
    state = State.STOP;
}
}
Dimitri Dewaele
  • 10,311
  • 21
  • 80
  • 127
  • 1
    Can you elaborate a bit on what the state machine is really doing? It helps me to come up with relevant suggestions. – Adriaan Koster Jul 01 '15 at 07:00
  • 1
    I'd definitely break these down into separate objects though - you're having to add methods every time you add a state. – Evan Knowles Jul 01 '15 at 07:06
  • Elaboration of the use case: This client polls a JMS queue and decides if it needs to print a message from a queue or needs to send some information back with JMS. – Dimitri Dewaele Jul 01 '15 at 07:08
  • 1
    "*was wondering if you Java gurus would **share your state-machine advice for this example***" Belongs on [CodeReview](http://codereview.stackexchange.com/) – Vince Jul 01 '15 at 07:25

0 Answers0