0

没有状态模式

public static void main(String[] args) {
    Context c = new Context();
    for (int i = 0; i < 10; i++)
        c.someMethod();
}

static class Context {
    public static final int STATE_A = 0;
    public static final int STATE_B = 1;

    private int state = STATE_A;

    public void someMethod() {
        switch (state) {
        case STATE_A:
            System.out.println("StateA.SomeMethod");
            state = STATE_B;
            break;
        case STATE_B:
            System.out.println("StateB.SomeMethod");
            state = STATE_A;
            break;
        default:
            break;
        }
    }
}

状态模式

public static void main(String[] args) {
        Context context = new Context();
        context.setState(new State1());
        for (int i = 0; i < 10; i++)
            context.someMethod();
    }

    static class Context {
        State state;

        void setState(State state) {
            this.state = state;
        }

        void someMethod() {
            state.someMethod();
            if (state instanceof State1) {
                state = new State2();
            } else {
                state = new State1();
            }
        }
    }

    static interface State {
        void someMethod();
    }

    static class State1 implements State {
        @Override
        public void someMethod() {
            System.out.println("StateA.SomeMethod");
        }
    }

    static class State2 implements State {
        @Override
        public void someMethod() {
            System.out.println("StateB.SomeMethod");
        }
    }

在第一种情况下,我们只有一个对象,但在另一种情况下,我们每次调用someMethod()方法时都会创建新对象。

  1. 这是对模式的正确理解吗?
  2. 我怎样才能解决这个问题而不创建这么多对象?
  3. 关于这种模式,我还需要了解什么?
4

2 回答 2

2

那么你可以做得更好:

您不得检查 instanceof 以进入新状态。
每个状态都应该能够在运行后立即进入下一个状态(示例:甚至没有尝试编译)。

例子:

class Context {  
    State state;                  

    public Context(){  
         state = STATE1;//Starting state
    }  

    void someMethod() { 
            state.someMethod(this);  //Which is it?State1 or state 2???
    }  

}

public interface States {  
    public static final State STATE1 = new State1();  
    public static final State STATE2 = new State2();   
    //more states here

}  

class State1 implements State {
     @Override         
      public void someMethod(Context ctx) {            
      System.out.println("StateA.SomeMethod");  
      ctx.setState(STATE2); //advance to next state        
  }
}

class State2 implements State {
    @Override         
    public void someMethod(Context ctx) {            
    System.out.println("StateB.SomeMethod");  
    ctx.setState(STATE1); //advance to next state (back to state 1)          
    }
}
于 2012-02-06T20:00:34.127 回答
2

在“经典”状态模式中,当前状态对象负责确定下一个状态。对于可能出现的问题,状态模式工作得非常好,并产生干净易懂的代码。

但是,当当前状态无法确定下一个状态时,它就会崩溃,而必须将此决定委托给调用者。如果问题足够大,代码很快就会变得难以理解,最好使用带有转换、动作和保护的 UMLish 状态机,其中状态更改可以由表驱动。

于 2012-02-06T21:11:19.580 回答