Java: Design pattern for working with state and inheritance

I will try to explain my problem on cars. I have AbstractCar and the users (developers) of my library will create many their ConcreteCars. This AbstractCar has state and this state is very important for right working of the library! Only the car can control its state (no any Drivers etc). The state changes in methods start/stop at the beginning and at the end of the methods. Besides all cars must implement interface Car.

public enum State{
   STARTING, STARTED, STOPPING, STOPPED
}

public interface Car{
   public void start();
   public void stop();
   public State getState();
}

I tried two variants.

Variant 1

public abstract class AbstractCar implements Car{
  private State state;
  public void setState(State state){...}
  public State getState(){...}
}

public class ConcreteCar extends AbstractCar{
  @Override
  public void start(){
     setState(stateK);
     ...
     setState(stateN);
  }

  @Override
  public void stop(){
     setState(stateR);
     ...
     setState(stateO);
  }
}

At variant 1 the user of the library will have to remember to change the state. If he forgets to do it, then there will be a bug in the code.

Variant 2

public abstract class AbstractCar implements Car{
  private State state;
  protected void doOnStart(){ }
  protected void doOnStop(){ }
  public final void start(){
    state=...;
    doOnStart();
    state=...;
  }
  public final void stop(){
    state=...;
    doOnStop();
    state=...;
  }
}

public class ConcreteCar extends AbstractCar{
  @Override
  protected void doOnStart(){
    ....
  }

  @Override
  protected void doOnStop(){
     ...
  }
}

In variant 2 the user can’t forget about state because it is already outside his control, but if I have many states and many methods in which they can be changed this is not a very good way.

Could anyone advise any pattern or technologies how to solve such problem?

Answer

In variant 2 the user can’t forget about state because it is already outside his control

And is it desirable ?

public abstract class AbstractCar implements Car{
   ...
  public final void start(){
    state=...;
    doOnStart();
    state=...;
  }
  ...
}

In the abstract class you determine for the concrete classes the state that they should be used.
It doesn’t seem a very flexible solution for concrete classes since a state change should depend on the context that may change in the start() method.

You should use abstract method in AbstractCar to both allow and force concrete classes to choose how define their state such as :

Suppose this concrete class :

public abstract class AbstractCar implements Car{
   ...
  public abstract State getStateBeforeStart();
  public abstract State getStateAfterStart();
  ...
  public final void start(){
    state = getStateBeforeStart();
    doOnStart();
    state = getStateAfterStart();
  }
  ...
}

You could also use Javadoc to document correctly the API of your classes and the responsibilities of concrete classes in order to favor a good use of it.

Leave a Reply

Your email address will not be published. Required fields are marked *