I am writing a java simulation application which has a lot of entities to simulate. Each of these entities has a certain state at any time in the system. A possible and natural approach to model such an entity would be using the state (or state machine) pattern. The problem is that it creates a lot of objects during the runtime if there are a lot of state switches, what might cause bad system performance. What design alternatives do I have? I want performance to be the main criteria after maintainability.
Thanks
My suggestion:
Have you “transitions managment” be configurable (i.e – via XML).
Load the XML to a repository holding the states.
The internal data structure will be a Map:
The reason for my selection is that this will be a map from a state name
To a map of “inputs” and new states:
Each map defines a map between possible input and the new state it leads to which is defined by the state name and a StateChangeHandler I will elaborate on later
change state method at the repository would have a signature of:
void changeState(StateOwner owner, String input)This way the repository is stateless in the sense of the state owner using it, you can copy one copy,
and not worry about thread safety issues.
StateOwner will be an interface your Classes that need state changing should implement.
I think the interface should look like this:
In addition, you will have a ChangeStateHandler interface:
When the repository’s changeState method is called, it will
check at the data structure that the current state of the stateOwner has a map of “inputs”.
If it has such a map, it will check if the input has a new State to change to, and invoke the onChangeState method.
I will suggest you have a default implementation of the StateChangeHandler, and of course sub classes that will define the state change behavior more explicitly.
As I previously mentioned, all this can be loaded from an XML configuration, and using reflection you can instantitate StateChangeHandler objects based on their name (as mentioned at the XML) and that will be held in the repository.
Efficiency and good performance rely and obtained using the following points:
a. The repository itself is stateless – no internal references of StateOwner should be kept.
b. You load the XML once , when the system starts, after that you should work with in memory data structure.
c. You will provide specific StateChangeHandler implementation only when needed, the default implementation should do basicaly nothing.
d. No need to instantiate new objects of Handlers (as they should be stateless)