状态模式 java
State pattern java
我正在 java
学习设计模式
我正在做一些 links.I 我正在尝试按状态模式设计洗衣机
我对状态设计模式的实现有疑问
public interface State {
public void openLid();
public void closeLid();
public void start();
public void stop();
public void washing();
}
public class Idle implements State{
//implementing overidden methods
.......
}
public class Washing implements State {
//implementing overidden methods
.......
}
public class WashingMachine {
State state;
public WashingMachine(State state) {
this.state = new Idle();
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
我想知道在空闲状态和清洗状态之间切换时,有两种方式可以通过网络查看
1.WashingMachine class 实现 State 接口并从 Idle[=33= 切换状态]到洗涤或反之亦然,基于某些条件
2.Idle 和 Washing class 有 WashingMachine 作为成员变量.
请任何人提出建议,我对实现部分有点困惑。
好的,让我们来看看你的两个想法:
1.)洗衣机是状态吗?不,绝对不。那为什么要实现state接口呢?
2.) 这几乎可行,但它使状态不可重用(对于像这样的小型实现来说还不错,但对于游戏之类的东西来说,这很糟糕)。它们只能是洗衣机的状态。如果我想将这些状态用于洗碗机怎么办?
你应该做什么:
创建一个接口或 class,类似于 StateManager,并让 WashingMachine 实现它,然后不使用具体的 class,而是在状态中创建一个 StateManager 字段。
示例:
public abstract class StateManager {
public State state;
public void setState(State newState) {
state = newState;
newState.parent = this;
}
public State getState() {
return state;
}
}
州:
public abstract class State {
public StateManager parent;
// Whenever you want to set the object's state, use this
}
示例状态:
public class WashingState extends State {
// your methods here
}
示例状态管理器:
public class WashingMachine extends StateManager {
// your methods here.
}
我改变了所有东西 zo classes 而不是界面,因为它们使创建一些对象更容易(比如如果你想制作洗碗机和洗衣机,那么你可以从它们中提取洗涤部分,并为其制作一个单独的 class)
我认为更好的选择是创建
public enum State{IDLE,WASHING};
并使用它。此 enum
甚至可以命名为 WashingMachineState
,因为您提到的状态仅指定给洗衣机 - 它们将不可重复使用,因此此处没有接口意义。
如果您想在不同设备之间共享相同的状态,例如。 WashingMachine
和 DishWasher
那么你可以使用
public interface Statefull{
public State getState();
public void changeState(State newState);
}
并让WashingMachine
和DishWasher
实现Statefull
接口。
使用 Java 8 的默认接口实现,您甚至可以在接口中包含 getter 实现,因此在实现 类.
时没有样板代码
在解决您的问题之前,我更愿意回顾一下模式的概念并建议您对代码进行一些小的修改。
状态模式允许对象在其内部状态改变时改变其行为。
在您的情况下,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 (对于每个处理),并且它还允许降低上下文的复杂性,因为当你使用状态模式时,你会得到一系列行为::
我们处于空闲状态时的行为位于IdleState
class。
我们处于洗涤状态时的行为位于WashingState
class.
等等...
要执行操作,状态实例需要上下文 (WashingMachine
)。
要解决这个问题,您有两种方法:
要么将 WashingMachine
对象存储为状态实例中的字段,要么在上下文 WashingMachine
对象将处理委托给状态时将其作为参数传递。
我建议你使用无状态的方式。
因此,当在 WashingMachine
实例上调用 startWashing()
操作时,WashingMachine
实例应通过传递自身(例如 state.startWashing(this)
)将处理委托给 state.startWashing()
。
国家应提供参数 a WashingMachine
:
public interface WashingMachineState {
void openLid(WashingMachine machine);
void closeLid(WashingMachine machine);
void pushStartBtn(WashingMachine machine);
void pushStopBtn(WashingMachine machine);
}
3) 实际上你定义了两种状态:idle 和 washing。
这些应该以 stopping
状态完成,因为当机器处于 "is stopping" 状态时,机器上的某些操作(例如开门、按下启动按钮...)具有特定行为。
请注意,只有两个状态,您可能还想知道该模式是否相关。
现在,我可以回答你的问题了。
I want to know when switching between state between idle to washing
the implementation there can be two ways which is saw over net
1.WashingMachine
class implements State interface and switch state from Idle to washing or vice versa based on some condition
2.Idle and Washing class has WashingMachine
as member variable.
WashingMachine
和 WashingMachineState
正在合作,但事情不同。
所以他们不能依赖同一个接口。
添加 WashingMachine
对象作为状态子 classes 的字段是可能的。
如前所述,您还可以将 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
修改说明:
changeState
在使用状态模式时比 setState
更有意义。
changeState(State)
可以使用 protected
修饰符来降低此方法的可见性,当然状态 subclasses 应该与 WashingMachine
。它是 Java 中启用的实现细节。对于其他 OOP 语言,您当然还有其他选择。
关于idle到washing的切换,我觉得应该只有在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){
...
}
}
我正在 java
学习设计模式我正在做一些 links.I 我正在尝试按状态模式设计洗衣机
我对状态设计模式的实现有疑问
public interface State {
public void openLid();
public void closeLid();
public void start();
public void stop();
public void washing();
}
public class Idle implements State{
//implementing overidden methods
.......
}
public class Washing implements State {
//implementing overidden methods
.......
}
public class WashingMachine {
State state;
public WashingMachine(State state) {
this.state = new Idle();
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
我想知道在空闲状态和清洗状态之间切换时,有两种方式可以通过网络查看
1.WashingMachine class 实现 State 接口并从 Idle[=33= 切换状态]到洗涤或反之亦然,基于某些条件
2.Idle 和 Washing class 有 WashingMachine 作为成员变量.
请任何人提出建议,我对实现部分有点困惑。
好的,让我们来看看你的两个想法:
1.)洗衣机是状态吗?不,绝对不。那为什么要实现state接口呢?
2.) 这几乎可行,但它使状态不可重用(对于像这样的小型实现来说还不错,但对于游戏之类的东西来说,这很糟糕)。它们只能是洗衣机的状态。如果我想将这些状态用于洗碗机怎么办?
你应该做什么:
创建一个接口或 class,类似于 StateManager,并让 WashingMachine 实现它,然后不使用具体的 class,而是在状态中创建一个 StateManager 字段。
示例:
public abstract class StateManager {
public State state;
public void setState(State newState) {
state = newState;
newState.parent = this;
}
public State getState() {
return state;
}
}
州:
public abstract class State {
public StateManager parent;
// Whenever you want to set the object's state, use this
}
示例状态:
public class WashingState extends State {
// your methods here
}
示例状态管理器:
public class WashingMachine extends StateManager {
// your methods here.
}
我改变了所有东西 zo classes 而不是界面,因为它们使创建一些对象更容易(比如如果你想制作洗碗机和洗衣机,那么你可以从它们中提取洗涤部分,并为其制作一个单独的 class)
我认为更好的选择是创建
public enum State{IDLE,WASHING};
并使用它。此 enum
甚至可以命名为 WashingMachineState
,因为您提到的状态仅指定给洗衣机 - 它们将不可重复使用,因此此处没有接口意义。
如果您想在不同设备之间共享相同的状态,例如。 WashingMachine
和 DishWasher
那么你可以使用
public interface Statefull{
public State getState();
public void changeState(State newState);
}
并让WashingMachine
和DishWasher
实现Statefull
接口。
使用 Java 8 的默认接口实现,您甚至可以在接口中包含 getter 实现,因此在实现 类.
在解决您的问题之前,我更愿意回顾一下模式的概念并建议您对代码进行一些小的修改。
状态模式允许对象在其内部状态改变时改变其行为。
在您的情况下,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 (对于每个处理),并且它还允许降低上下文的复杂性,因为当你使用状态模式时,你会得到一系列行为::
我们处于空闲状态时的行为位于
IdleState
class。我们处于洗涤状态时的行为位于
WashingState
class.等等...
要执行操作,状态实例需要上下文 (WashingMachine
)。
要解决这个问题,您有两种方法:
要么将 WashingMachine
对象存储为状态实例中的字段,要么在上下文 WashingMachine
对象将处理委托给状态时将其作为参数传递。
我建议你使用无状态的方式。
因此,当在 WashingMachine
实例上调用 startWashing()
操作时,WashingMachine
实例应通过传递自身(例如 state.startWashing(this)
)将处理委托给 state.startWashing()
。
国家应提供参数 a WashingMachine
:
public interface WashingMachineState {
void openLid(WashingMachine machine);
void closeLid(WashingMachine machine);
void pushStartBtn(WashingMachine machine);
void pushStopBtn(WashingMachine machine);
}
3) 实际上你定义了两种状态:idle 和 washing。
这些应该以 stopping
状态完成,因为当机器处于 "is stopping" 状态时,机器上的某些操作(例如开门、按下启动按钮...)具有特定行为。
请注意,只有两个状态,您可能还想知道该模式是否相关。
现在,我可以回答你的问题了。
I want to know when switching between state between idle to washing the implementation there can be two ways which is saw over net
1.
WashingMachine
class implements State interface and switch state from Idle to washing or vice versa based on some condition2.Idle and Washing class has
WashingMachine
as member variable.
WashingMachine
和 WashingMachineState
正在合作,但事情不同。
所以他们不能依赖同一个接口。
添加 WashingMachine
对象作为状态子 classes 的字段是可能的。
如前所述,您还可以将 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
修改说明:
changeState
在使用状态模式时比setState
更有意义。changeState(State)
可以使用protected
修饰符来降低此方法的可见性,当然状态 subclasses 应该与WashingMachine
。它是 Java 中启用的实现细节。对于其他 OOP 语言,您当然还有其他选择。
关于idle到washing的切换,我觉得应该只有在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){
...
}
}