Паттерн штатов: почему штаты не являются синглетонами? - PullRequest
1 голос
/ 22 июня 2010

Я использовал шаблон State для реализации простого конечного автомата.Глядя на описание, данное в Википедии , а точнее на предлагаемую реализацию Java, я удивился, почему классы, реализующие интерфейс State (т.е. различные состояния), не являются синглетонами?

ВВ предлагаемой реализации новое состояние создается всякий раз, когда происходит переход.Однако для представления каждого состояния достаточно одного объекта.Итак, зачем тратить время на создание нового экземпляра каждый раз, когда происходит переход?

Ответы [ 5 ]

10 голосов
/ 22 июня 2010

Поскольку в каждом штате могут храниться переменные экземпляра?

Взгляните на пример из Википедии, на который вы ссылаетесь:

class StateB implements State { 
    private int count=0; 
    public void writeName(StateContext stateContext, String name) { 
        System.out.println(name.toUpperCase()); 
        if(++count>1) { 
            stateContext.setState(new StateA()); 
        }
    }
}

Можете ли вы увидеть, как оно хранит количество раз, которое онобыл введен?

Теперь в FSM вы, вероятно, хотите, чтобы каждое состояние было идемпотентным (последующие вызовы дают ту же обратную связь), но шаблон состояний более общий.Одно из целевых применений, как описано на странице википедии:

Чистый способ частичного изменения своего типа во время выполнения

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

1 голос
/ 23 июня 2010

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

Вот простой конечный автомат, который повторно использует состояния, но неt сделать их одиночными.

public class SwitchState
{
    public SwitchState(bool isOn)
    {
        mIsOn = isOn;
    }

    public void InitToggleState(SwitchState state)
    {
        mToggleState = toggleState;
    }

    public bool IsOn { get { return mIsOn; } }
    public SwitchState Toggle() { return mToggleState; }

    private SwitchState mToggleState;
    private bool mIsOn;
}

public class LightSwitch
{
    public LightSwitch()
    {
        mState = sOnState;
    }

    public bool IsOn { get { return mState.IsOn; } }

    public void Toggle()
    {
        mState = mState.Toggle();
    }

    static LightSwitch()
    {
        sOnState = new SwitchState(true);
        sOffState = new SwitchState(false);

        sOnState.InitToggleState(sOffState);
        sOffState.InitToggleState(sOnState);
    }

    private static SwitchState sOnState;
    private static SwitchState sOffState;

    private SwitchState mState;
}

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

1 голос
/ 22 июня 2010

Вам может потребоваться объект «Stateful-State» (как показано на примере один пример на странице ссылок в Википедии), и, кроме того, вы можете запустить несколько конечных автоматов одного типа в одной и той же JVM.

Это было бы невозможно, если бы каждый штат был Синглтоном.

1 голос
/ 22 июня 2010

Предположим, что ваш объект имеет состояние. А что если вам понадобится «еще одна такая вещь»?

0 голосов
/ 22 июня 2010

Вопрос должен быть задан наоборот: почему State как синглтон? Синглтон необходим только в том случае, если вам требуется глобальный доступ, а ошибка - иметь более одного экземпляра.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...