GOF State Pattern Проблемы реализации государственного перехода - PullRequest
3 голосов
/ 02 июля 2010

Во-первых, кто-нибудь может объяснить, как объект состояния может использоваться совместно, когда у объекта состояния нет переменных экземпляра?

Этот текст взят из GOF, стр. 308, пункт 3 (раздел о последствиях):

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

Может кто-нибудь объяснить этот текст?

Во-вторых, каковы подходы к решению о переходе государства? Я имею ввиду решение какого следующего государства размножать?

Пожалуйста, помогите. Благодарю.

Ответы [ 2 ]

2 голосов
/ 06 июля 2010

В шаблоне состояния у вас есть представление состояния объекта с помощью объектов состояния. Эти объекты состояния представляют определенное состояние, но они не не имеют своего собственного изменяемого состояния. Это означает, что они никогда не меняются. Следовательно, любое количество объектов может одновременно использовать один и тот же объект состояния (даже из разных потоков). Если бы объект состояния имел изменяемое состояние, другие объекты должны были бы беспокоиться об изменении своего объекта состояния из другого места.

Использование одного экземпляра объекта многими другими можно рассматривать как экземпляр шаблона flyweight .

Что касается второй части вашего вопроса, вот пример:

class SomeStateMachine;

class AbstractState {
    // abstract baseclass for all state-classes
    void input(const std::string & data, SomeStateMachine & caller) = 0;
}

class FinalState : public AbstractState {
    FinalState * getInstance(); // always returns same instance
}

class InitialState : public AbstractState {
public:
    InitialState * getInstance(); // always returns same instance
    void input(const std::string & data, SomeStateMachine & caller) {
        std::cout << data << std::endl;
        caller.m_State = FinalState::getInstance();
    }
}

class SomeStateMachine {
public:
    SomeStateMachine() : m_State(InitialState::getInstance())
    void input(const std::string & data) {
        m_State->input(data, *this);
    }
private:
    friend class InitialState;
    AbstractState * m_State;
};

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

2 голосов
/ 02 июля 2010

В этом параграфе в основном говорится, что вы кодируете свои состояния как отдельные классы - тогда тип экземпляра - это «состояние», и классам не нужны переменные экземпляра, потому что их тип кодирует всю необходимую вам информацию.

Например, я хочу иметь три состояния: «Открыто», «Активно» и «Закрыто».Я мог бы определить следующие классы:

abstract class State {};

class Open extends State {

  public Open() {}

}

class Active extends State {

  public Active() {}

}

class Closed extends State {

  public Closed() {}

}

-

Другой вариант - я подозреваю, что это комбинация с навесным весом, на который намекают в тексте GOF, будет создание состояниякласс, который представляет собой набор статических членов (по одному для каждого состояния), которые затем могут быть разделены -

public class State {

  private string name;

  private State(String name) {
    this.name = name;
  }

  public final static State OPEN = new State("Open");
  public final static State ACTIVE = new State("Active");
  public final static State CLOSED = new State("Closed");

}

Мне пришлось копать, чтобы напомнить себе, как все это работает в деталях.У Кериевского есть хорошее описание этого (я сильно позаимствовал из одного из его примеров выше!) И того, как переходы состояний могут обрабатываться путем подклассов из класса состояний, чтобы создавать классы, которые управляют каждым переходом.См. «Рефакторинг к шаблонам» (ISBN: 0321213351)

РЕДАКТИРОВАТЬ (2): На его веб-сайте приведена диаграмма классов для его примера - http://www.industriallogic.com/xp/refactoring/alteringConditionalsWithState.html

alt text

...