Подтвердить что ты не робот

В чем разница между конечным автоматом и реализацией государственного образца?

Интересно, является ли конечный автомат только шаблоном состояния на работе или существует ли разница между этими двумя?

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

4b9b3361

Ответ 1

То, как я описываю это различие для моих коллег, состоит в том, что шаблоны состояний - это более децентрализованная реализация многих автономных инкапсулированных состояний, тогда как государственные машины более монолитные. Монолитный характер государственных машин означает, что одно состояние будет сложнее повторно использовать на другой машине и что сложнее разбить машину состояний на несколько единиц компиляции. С другой стороны, этот монолитный дизайн позволяет гораздо лучше оптимизировать государственные машины и позволяет многим реализациям представлять всю информацию о переходе в одном месте в таблице. Это особенно подходит для ситуаций, когда лицо, ответственное за архитектуру или функцию государственного компьютера, не очень хорошо разбирается в языке программирования, в котором оно реализовано. Помните, что многие инженерные и математические специальности изучили государственные машины, но мало или вообще не получили образования в поля программирования. Гораздо легче представить этим типам людей таблицу переходов, действий и стражей, чем страницы и страницы государственных моделей.

Хотя статья действительно была хорошей, я не согласен с автором в нескольких моментах:

  • "Нет смысла больше использовать государственные машины, когда вы используете объектно-ориентированный язык программирования", это категорически неверно, если у вас есть какие-либо требования к скорости выполнения.
  • Идея о том, что внедрение авторов особенно короткая или простая, или что она требует меньшего обслуживания, чем цифровая камера с улучшенными состояниями, зависит от вашего прецедента и личного вкуса, но не может быть сказано катагорически. http://www.boost.org/doc/libs/1_55_0/libs/statechart/doc/tutorial.html#IntermediateTopicsADigitalCamera

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

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

С точки зрения обслуживания следует отметить, что запись необработанных событий не может быть выполнена из одной центральной сверхдержавы с шаблоном состояния. Кроме того, добавление новой функции типа/обработчика события требует добавления функции ко всем состояниям! Я не считаю это полезным.

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

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

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

Ответ 2

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

Например, вы можете взглянуть на исследование Миро Самека, прочитав книгу Практические диаграммы состояний UML в C/С++, 2-е изд. (Управляемое событиями программирование для встроенных систем)

Вы также можете найти интересный этот вопрос.

Ответ 3

конечный автомат - это только шаблон состояния при работе или если на самом деле существует разница между этими двумя

TL; DR: Представьте, что вам нужно заменить состояние другим поведением. Тогда представьте, что вам нужно добавить новое состояние.

Полный ответ. Есть большая разница.

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

Государственный автограф абстрагирует собственно диаграмму состояния и отделяет ее от полезной нагрузки перехода. Чтобы изменить конкретное состояние, вы должны исправить всю диаграмму. Но чтобы добавить состояние или переход, вам нужно только исправить диаграмму.

Ответ 4

В случае, если кто-то еще заинтересован, вот мое мнение:

В конечном автомате объект может находиться в разных состояниях, но нам все равно, как они себя ведут в этих состояниях. На самом деле, нас интересует, какое действие применяется, когда объект переходит в следующее состояние. Если вы реализуете конечный автомат в Java, состояние будет просто перечислением или String, и будет класс Transition с методом doAction().

С другой стороны, в паттерне состояний вас не заботит переход, а то, как объект ведет себя в этих состояниях. Переход - это просто детали реализации, позволяющие отделить поведение вашего состояния друг от друга. Каждое состояние будет отдельным классом, имеющим собственный метод doAction().

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

Но для варианта использования, например, для заказа онлайн-продуктов, когда вам все равно, как ведет себя объект заказа. Вам важно только, если заказ находится в состоянии "add_to_cart", когда публикуется событие "payment_finished", а затем измените его на состояние "обработка". В этом случае состояние является простым свойством перечисления класса Order, поэтому использование конечного автомата намного лучше.

Ответ 5

Я замечаю разницу с состоянием Pattern. это более удобно при использовании его для пользовательского интерфейса. допустим, я хотел заблокировать состояние. в контексте шаблона состояния я мог бы создать логическое значение и предотвратить дальнейшее изменение состояний.

Вот пример Kotlin:

     inner class StateContext : State {

       private var stateContext: State? = null
       private var lockState: Boolean = false

       fun isLockState(): Boolean {
           return lockState
       }

       fun setLockState(lockState: Boolean): StateContext {
           this.lockState = lockState//no further actions allowed. useful if you need to permenatley lock out the user from changing state.
           return this
       }

       fun getState(): State? {
           return this.stateContext
       }

       fun setState(state: State): StateContext {
           if (!lockState) this.stateContext = state
           return this
       }

       override fun doAction() {
           this.stateContext?.doAction()
       }
   }

с конечным автоматом я не уверен, как это будет легко сделать.

Мне очень нравится конечный автомат, когда я беспокоюсь только о состоянии (например, сохранение перечисления текущего состояния), а не о фактических деталях реализации (например, об изменении цвета кнопок пользовательского интерфейса). Единственное, что хорошо в конечном автомате, это то, что вы можете иметь центральное место для регистрации изменений состояния. я видел эту библиотеку для kotlin by tinder, что выглядит интересно. но я лично думаю, что вы можете изменить их все, чтобы делать то, что вы хотите, просто чище один путь против другого.

что такое StateMachine тогда? StateMachine больше заботится о том, "что будет следующим состоянием", о его выделении перехода состояний, а не о его деталях. Это поддерживает поток. Обычно вы создаете его, используя перечисления. эта статья помогает прояснить ее (и ссылки, приведенные ниже, взяты оттуда, чтобы прояснить различия), но по сути это будет конечный автомат:

public enum LeaveRequestState {

Submitted {
    @Override
    public LeaveRequestState nextState() {
        return Escalated;
    }

    @Override
    public String responsiblePerson() {
        return "Employee";
    }
},
Escalated {
    @Override
    public LeaveRequestState nextState() {
        return Approved;
    }

    @Override
    public String responsiblePerson() {
        return "Team Leader";
    }
},
Approved {
    @Override
    public LeaveRequestState nextState() {
        return this;
    }

    @Override
    public String responsiblePerson() {
        return "Department Manager";
    }
};

public abstract LeaveRequestState nextState(); 
public abstract String responsiblePerson();

}

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

LeaveRequestState state = LeaveRequestState.Submitted;

state = state.nextState();
assertEquals(LeaveRequestState.Escalated, state);

state = state.nextState();
assertEquals(LeaveRequestState.Approved, state);

state = state.nextState();
assertEquals(LeaveRequestState.Approved, state);