状态模式java

cod*_*r25 5 java state design-patterns

我正在学习java中的设计模式

我正在通过一些链接.我正在尝试按州模式设计一台洗衣机

我有一个关于状态设计模式实现的查询

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;
   }

 }
Run Code Online (Sandbox Code Playgroud)

我想知道什么时候在空闲状态和清洗之间切换实现,有两种方法可以看到网络

1. WashingMachine 类根据某些条件实现状态接口并从空闲状态切换到清洗状态或反之亦然

2. IdleWashing类有WashingMachine作为成员变量.

请任何人都可以建议我对实现部分有点困惑.

dav*_*xxx 6

在解决您的问题之前,我更喜欢回顾一下该模式的想法,并建议您对代码进行一些小的修改。

状态模式允许对象在其内部状态发生变化时改变其行为。

在您的情况下,Idle 和 Washing 是作为状态的良好候选者,而 WashingMachine 是承载状态对象的良好候选者。

不过,三点说明:

1)状态提供的方法应该是一些动作,根据对象所处的状态而实现不同的动作。

在您的声明中:

public interface WashingMachineState {    
   public void openLid();
   public void closeLid();
   public void start();
   public void stop();
   public void washing();
  } 
Run Code Online (Sandbox Code Playgroud)

washing()不是一个动作而是一个状态。
start()将状态从闲置变为洗涤的动作。

在状态模式中,具有状态的对象被称为上下文
在你的例子中,上下文是WashingMachine.

2)在状态模式中,其思想是上下文想要执行一些行为根据当前状态而变化的动作。
为了实现这一点,上下文将其处理委托给其当前状态实例。
它避免了上下文中(对于每个处理)有许多if - else if ,并且它还允许降低上下文的复杂性,因为当您使用状态模式时,您会得到一系列行为: :

  • 当我们处于空闲状态时的行为位于类中IdleState

  • 当我们处于洗涤状态时的行为位于WashingState类中。

  • 所以对于...

为了执行操作,状态实例需要上下文 ( WashingMachine)。
要解决这个问题,您有两种方法:

WashingMachine对象存储为状态实例中的字段,或者在上下文WashingMachine对象将处理委托给状态时将其作为参数传递。

我建议你使用无状态的方式。
因此,当在实例startWashing()上调用操作时WashingMachineWashingMachine实例应通过传递自身来将处理委托给实例,state.startWashing()例如state.startWashing(this).
国家应提供参数 a WashingMachine

public interface WashingMachineState {    
   void openLid(WashingMachine machine);
   void closeLid(WashingMachine machine);
   void pushStartBtn(WashingMachine machine);
   void pushStopBtn(WashingMachine machine);
} 
Run Code Online (Sandbox Code Playgroud)

3)实际上你定义了两种状态:空闲和清洗。
这些应该在一个状态下完成stopping,因为当机器处于“正在停止”状态时,机器上的一些操作(例如打开门、按下启动按钮...)具有特定的行为。
请注意,只有两种状态,您可能还想知道该模式是否相关。


现在,我可以回答你的问题了。

我想知道当在空闲状态和清洗实现之间切换时,可以有两种通过网络看到的方法

1.WashingMachine类实现State接口,并根据某些条件将状态从空闲切换到洗涤,反之亦然

2.Idle和Washing类有WashingMachine成员变量。

WashingMachineWashingMachineStates 正在合作,但不同的事情。
所以他们必须不依赖相同的接口。
添加WashingMachine对象作为状态子类的字段是可能的。
正如所解释的,您还可以传递WashingMachineState 方法的 as 参数。

请注意,它并不是直接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;
   }

 }
Run Code Online (Sandbox Code Playgroud)

关于修改的说明WashingMachine

  • changeStatesetState当使用状态模式时更有意义。

  • changeState(State)可以使用protected修饰符来降低此方法的可见性,当然状态子类应该与WashingMachine. 它是 Java 中启用的实现细节。对于其他 OOP 语言,您当然还有其他选择。

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