Государственный образец и охрана

Обновление:

Шаблон состояния может быть неправильным способом решения этой проблемы. Следовательно, приветствуется любой другой узор. В основном я ищу способ иметь защитные условия для каждого состояния, но при этом иметь чистый и поддерживаемый код. Каким образом внешние системы маршрутизации, такие как emberjs, ui-router и response-router, будут реализовывать guard conditions, чтобы избежать перехода в определенное состояние, если условие не выполняется?


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

If error -> error state
If A && B && C -> second state
If only A -> first state

В любом состоянии, при ошибке, мы переходим в состояние ошибки. входы (события) A, B и C могут поступать в любом порядке, но если все они проходят, мы переходим во 2-е состояние. Если применяется только вход A, мы переходим в 1-е состояние.

Следующая диаграмма состояний взята из книги Мартина Фаулера по определенному языку предметной области.

DSL

В описании он говорит:

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

Подчеркиваю, что turning light и opening 2nd drawer могут происходить в любом порядке. То же, что A, B и C.

На основе комментария @SQLPolice и книги я нарисовал это:

введите описание изображения здесь

Но проблема в том, что я мог бы (A && B && C && D && D && E). В этом случае будет обременительно иметь все промежуточные состояния комбинации.


person Sam R.    schedule 01.07.2015    source источник
comment
у вас есть начальное состояние, я полагаю?   -  person SQL Police    schedule 01.07.2015
comment
Что вы это рисуете в ... UML / Flow ...?   -  person David Barker    schedule 01.07.2015
comment
@DavidBarker, тоже. Мне просто нужно что-то наглядное, чтобы понять, как реализовать.   -  person Sam R.    schedule 01.07.2015
comment
Хорошо, но когда у вас только A, вы хотите перейти в другое состояние. Но что произойдет, если у вас будет A в качестве первого события? Откуда вы знаете, что B или C последуют за вами?   -  person SQL Police    schedule 01.07.2015
comment
О, вот красивый рисунок! - Да, вы правы, при усложнении получается очень-очень громоздко. Вот почему вы используете инструменты для создания таких конечных автоматов - например, lex, flex и т. Д. (Для лексического анализа). Они создают код на языке C с множеством меток и goto прыжков ...   -  person SQL Police    schedule 01.07.2015


Ответы (3)


Для этого вы можете использовать какую-либо форму лексического анализа. Я бы подошел к этому, ограничив возможность перехода из состояния, если не соблюдаются ограничения, наложенные на границу между двумя состояниями. Недавно я написал FSM на PHP для фреймворка Laravel, в котором есть пример, подобный этому, где все ограничения должны быть истинными, прежде чем может произойти переход. Он использует псевдосостояния или дескрипторы внутри состояния для переключения флага, указывающего, что процесс завершен. Переход состояния возможен только тогда, когда все флаги установлены в значение true.

Пример анализа лексического состояния

Используя пакет FSM, который я написал для laravel, пример установки FSM будет выглядят примерно так.

Каждое состояние (либо onEnter), либо через псевдосостояние установило бы свой флаг ограничения на FSM OR State в значение true.

Это также вызовет checkReady(), который вызовет переход или сохранит текущее состояние на основе флагов ограничения.

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

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

Когда вы смотрите на одно состояние с псевдосостояниями / обработчиками. Состояние будет выглядеть примерно так, в котором заключена его логика.

person David Barker    schedule 01.07.2015

Быстрый черновик выглядит так:

введите описание изображения здесь

person SQL Police    schedule 01.07.2015
comment
Спасибо, но как мне не писать if (A && B && C)? Причина в том, что у меня уже есть много if и else с разными условиями. Единственная причина выбрать конечный автомат - это не делать этого. - person Sam R.; 01.07.2015
comment
Ах я вижу. Что за этим стоит - это домашнее задание для школы или что вы хотите реализовать? - person SQL Police; 01.07.2015
comment
Это не домашнее задание. Я старше таких вещей. Это настоящая проблема, и мы пытаемся ее упростить. - person Sam R.; 01.07.2015
comment
Это было давно, но я примерно помню, как это было сделано с помощью лексического анализа. Вы можете растворить A, B и C, используя последовательность промежуточных состояний, например: если у вас есть A, затем переключитесь в промежуточное состояние 1. Теперь, вот, если у вас есть B, тогда переходите в промежуточное состояние 2, но если нет, то перейдите в ваше конечное состояние 1. В промежуточном состоянии 1, если у вас есть C, перейдите в конечное состояние 2. Это один из возможных способов, как это сделали бы автоматические инструменты. - person SQL Police; 01.07.2015
comment
Сделайте событие перехода D где D = (A && B && C)? - person Fuhrmanator; 02.07.2015

Абстракция конечного автомата состоит из:

  1. состояния
  2. События или входы
  3. Переходы
  4. Действия

Оператор, подобный && b && c, по сути, является событием или вводом ... меткой перехода. Поэтому его необходимо сопоставить с событием, если вы собираетесь вписаться в абстракцию конечного автомата. Вам нужно написать код для этого сопоставления.

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

person John R. Hogerhuis    schedule 28.01.2016