在解决您的问题之前,我更喜欢回顾一下该模式的想法,并建议您对您的代码进行一些小的修改。
状态模式允许对象在其内部状态发生变化时改变其行为。
在您的情况下,Idle 和 Washing 是作为状态的良好候选者,而 WashingMachine 是承载状态对象的良好候选者。
但是,三个备注:
1) 状态提供的方法应该是一些动作,根据对象所处的状态,实现不同。
在您的声明中:
public interface WashingMachineState {
public void openLid();
public void closeLid();
public void start();
public void stop();
public void washing();
}
washing() 不是动作而是状态。
正是 start() 操作将状态从空闲更改为正在清洗。
在状态模式中,具有状态的对象被命名为上下文。
在您的情况下,上下文是WashingMachine。
2) 在状态模式中,想法是上下文想要执行一些行为根据当前状态改变的动作。
为此,上下文将其处理委托给其当前状态实例。
它避免在上下文中(对于每个处理)有许多 if - else if,并且它还允许降低上下文的复杂性,因为当您使用状态模式时,您会得到一系列行为: :
要执行这些操作,状态实例需要上下文 (WashingMachine)。
要解决这个问题,您有两种方法:
要么将WashingMachine 对象作为字段存储在状态实例中,要么在上下文WashingMachine 对象将处理委托给状态时将其作为参数传递。
我建议你使用无状态方式。
因此,当在WashingMachine 实例上调用startWashing() 操作时,WashingMachine 实例应通过传递自身(例如state.startWashing(this))将处理委托给state.startWashing()。
该州应提供WashingMachine作为参数:
public interface WashingMachineState {
void openLid(WashingMachine machine);
void closeLid(WashingMachine machine);
void pushStartBtn(WashingMachine machine);
void pushStopBtn(WashingMachine machine);
}
3) 实际上你定义了两种状态:空闲和洗涤。
这些应该以stopping 状态完成,因为机器上的某些操作(例如打开门、按下启动按钮...)在机器处于“停止”状态时具有特定行为。
请注意,只有两种状态,您可能还想知道模式是否相关。
现在,我可以回答你的问题了。
我想知道什么时候在空闲状态和洗涤状态之间切换
实现可以有两种方式,可以通过网络看到
1.WashingMachine类实现State接口,根据某些条件将状态从空闲切换到洗涤,反之亦然
2.Idle 和 Washing 类有WashingMachine 作为成员变量。
WashingMachine 和 WashingMachineStates 是合作的,但不同的东西。
所以他们不必依赖同一个接口。
添加WashingMachine 对象作为状态子类的字段是可能的。
如前所述,您还可以将 WashingMachine 作为 State 方法的参数传递。
请注意,不是直接由WashingMachine 执行从一个状态到另一个状态的切换。
这是由国家执行的。
并且各州应该调用WashingMachine.changeState() 来执行它。
WashingMachine 可以是:
public class WashingMachine {
private WashingMachineState state;
public WashingMachine() {
this.state = new Idle();
}
protected void changeState(WashingMachineState state) {
this.state = state;
}
public void openLid(){
state.openLid(this);
}
public void closeLid(){
state.closeLid(this);
}
public void pushStartBtn(){
state.pushStartBtn(this);
}
public void pushStopBtn(){
state.pushStopBtn(this);
}
public State getState() {
return state;
}
}
WashingMachine 修改说明:
关于从空闲切换到洗涤,我认为应该只有在IdleState状态下才可以调用pushStartBtn()。
这是一个例子:
public class IdleState implements State {
public void openLid(WashingMachine machine){
...
}
public void closeLid(WashingMachine machine){
...
}
public void pushStartBtn(WashingMachine machine){
//do processing with machine to begin effectively the washing
...
machine.changeState(new WashingState());
}
public void pushStopBtn(WashingMachine machine){
...
}
}