Java:用于处理状态和继承的设计模式

Pav*_*l_K 5 java design-patterns

我会尝试解释我在汽车上的问题.我有AbstractCar,我的库的用户(开发人员)将创建许多他们的ConcreteCars.这个AbstractCar有状态,这个状态对于图书馆的正确工作非常重要!只有汽车可以控制其状态(没有任何司机等).方法的状态变化在方法的开始和结束时开始/停止.除了所有汽车必须实现接口汽车.

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

public interface Car{
   public void start();
   public void stop();
   public State getState();
}
Run Code Online (Sandbox Code Playgroud)

我尝试了两种变体.

变式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);
  }
}
Run Code Online (Sandbox Code Playgroud)

在变体1中,库的用户必须记住改变状态.如果他忘记这样做,那么代码中就会出现错误.

变体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(){
     ...
  }
}
Run Code Online (Sandbox Code Playgroud)

在变体2中,用户不能忘记状态,因为它已经超出了他的控制范围,但是如果我有许多状态和许多可以改变它们的方法,这不是一个非常好的方法.

任何人都可以建议任何模式或技术如何解决这样的问题?

dav*_*xxx 0

在变体 2 中,用户无法忘记状态,因为状态已经超出了他的控制范围

这是可取的吗?

public abstract class AbstractCar implements Car{
   ...
  public final void start(){
    state=...;
    doOnStart();
    state=...;
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

在抽象类中,您可以为具体类确定应使用它们的状态。
对于具体类来说,这似乎不是一个非常灵活的解决方案,因为状态更改应该取决于 start() 方法中可能更改的上下文。

您应该在 AbstractCar 中使用抽象方法来允许和强制具体类选择如何定义其状态,例如:

假设这个具体类:

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

您还可以使用 Javadoc 正确记录类的 API 和具体类的职责,以便更好地使用它。