Должен ли конечный автомат выставлять свое текущее состояние? - PullRequest
8 голосов
/ 23 марта 2011

Мы используем «фреймворк» конечного автомата (основанный на шаблоне состояний), который не отображает его текущее состояние, что иногда означает, что я должен что-то делать окольным путем.

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

Это правильно? Я не очень разбираюсь в государственных машинах.

(Я спрашиваю здесь, потому что я знаю, что у меня есть присущее смещение против Паттерна состояний, который я считаю слишком многословным.)

Пример

Представьте себе систему, которая в одном из состояний считывает два датчика. Один датчик дает числовое значение, другой дает логическое значение, которое сообщает вам, является ли первый «надежным» или нет. Система выводит значение, которое является либо текущим «хорошим» значением, либо интерполяцией (или каким-либо другим необычным расчетом) на основе последних n хороших значений.

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

(я думаю, что я ответил на свой вопрос: решение будет состоять в том, чтобы в конечном автомате было событие NewDataValue(val), которое передавало бы значение только из «хорошего» состояния?)

Ответы [ 4 ]

10 голосов
/ 23 марта 2011

Я должен согласиться с человеком, который сделал «неправильное использование» комментария.

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

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

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

Фактически, сама идея изменения события на основе текущего состояния бросает вызов инкапсуляции.

Лучшие автоматы имеют очень простую форму:

                         +------+
                         |      | state
                         V      |  transitions
            +---------------+   |
 events --> |               | --+
            | state machine |
effects <-- |               |
            +---------------+

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


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

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

2 голосов
/ 23 марта 2011

«если вам нужно знать текущее состояние, вы используете его неправильно». - Это правильно.

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

2 голосов
/ 23 марта 2011

Ну, это настоящий вопрос.Зачем вам нужно знать текущее состояние конечного автомата?Что вы планируете делать с ним?

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

Возможно, конечный автомат - это черный ящик (или, в некоторых случаях, похоже на игровой автомат!), КоторыйВы вводите данные в и извлекаете данные из них.

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

Итак, непрозрачность структуры на самом деле не проблема,это то, что вы пытаетесь сделать с информацией, если или когда вы ее получите.

0 голосов
/ 21 сентября 2011

При проектировании иерархических систем обычно объект более высокого уровня знает только абстракцию состояния объекта более низкого уровня, например абстрактное состояние state_good (совершенное, приемлемое, ...) и абстрактное состояние state_bad (fail1, failed2, failed3 ..).

В неиерархических системах один объект может точно знать состояние другого объекта, особенно если объектам назначаются разнородные задачи.

-Janusz

...