Непонимание государственной картины - PullRequest
0 голосов
/ 06 февраля 2012

Без шаблона состояния

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. Что еще мне нужно знать об этом шаблоне?

Ответы [ 2 ]

2 голосов
/ 07 февраля 2012

В «классическом» шаблоне состояний ответственность за определение следующего состояния лежит на объекте текущего состояния. Для задач, где это возможно, шаблон состояний работает очень хорошо и создает чистый и понятный код.

Однако оно ломается, когда текущее состояние не может определить следующее состояние, но должно делегировать это решение вызывающей стороне. Если проблема достаточно велика, код вскоре станет непонятным, и лучше использовать UMLish-конечный автомат с переходами, действиями и средствами защиты, где изменения состояния могут управляться таблицами.

2 голосов
/ 07 февраля 2012

Ну, вы можете сделать лучше:

Вы не должны проверять 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)          
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...