I want to implement FSM like below
ACTIVE_WAITING_STATE , ACTIVE_RUNNING_STATE , ACTIVE_END_STATE, so on PASSIVE_WAITING_STATE, PASSIVE_RUNNING_STATE, PASSIVE_END_STATE, so on
most functionalities are common for ACTIVE and PASSIVE states, just some small functions overrided. There is no problem until here. Problem is, All third level group have common functions. I mean, For example I have to implement 2 different increment() function one of is ACTIVE_xxx_STATEs, another one is PASSIVE_xxx_STATEs. How to do this without re-written for all states (eg. ACTIVE_WAITING_STATE , ACTIVE_RUNNING_STATE , ACTIVE_END_STATE, and also PASSIVE states)
To clearify my questions, my ugly sol'n. Problem is increment functions is same and re-written for all ActivexxxState (and also PassiveXXXState).
public class BaseState {
// Lots of functions
}
public class WaitingState extends BaseState{
// Lots of functions
}
public class RunningState extends BaseState{
// Lots of functions
}
public class EndState extends BaseState{
// Lots of functions
}
public Class ActiveWaitingState extends WaitingState {
// Few unique functions
private void increment() {
System.out.println("increment active");
}
}
public Class ActiveRunningState extends RunningState {
// Few unique functions
private void increment() {
System.out.println("increment active");
}
}
public Class ActiveEndState extends EndState {
// Few unique functions
private void increment() {
System.out.println("increment active");
}
}
public Class PassiveWaitingState extends WaitingState {
// Few unique functions
private void increment() {
System.out.println("increment passive");
}
}
public Class PassiveRunningState extends RunningState {
private void increment() {
System.out.println("increment passive");
}
}
public Class PassiveEndState extends EndState {
private void increment() {
System.out.println("increment passive");
}
}
I would make increment() a protected method in BaseState so it is implemented once.
I have written an article on using enums to build a state machine. This can avoid the need to create classes everywhere for each state and still support some inheritance.
In answer to your comment.
abstract class BaseState {
public abstract boolean isPassive();
public boolean increment() {
System.out.println("increment "+(isPassize() ? "passive" : "active");
}
}
class PassiveState {
public boolean isPassive() { return true; }
}
If you don't want to have multiple isPassive methods you could assume a class naming convention
public boolean isPassive() { return getClass().getSimpleName().startsWith("Passive"); }