У моего автомата верхнего уровня есть некоторые состояния и ребра. Я назову это родительским конечным автоматом.
A ----> B ----> C
Любое состояние внутри родительского конечного автомата также может быть конечным автоматом. Я назову этих детей государственными машинами.
___________
/ \
A ----> | B0->B1->B2 | ----> C
\____________/
Если родительский конечный автомат переходит от A к B, конечный автомат B вступает во владение. После завершения работы B, как ему следует отказаться от управления родительским конечным автоматом и перейти в состояние C? Какой шаблон дизайна вы используете?
Если вам интересно, у меня есть дочерние конечные автоматы в родительских конечных автоматах, потому что мой точный проект довольно сложен, и естественно инкапсулировать внутреннюю работу дочернего состояния.
MachineContainer
класс дляB
этого, который содержит B0, B1 и B2, и когда B2 завершается, он передает управление обратно в свой контейнер, который затем переходит в C ... Хотя я никогда не пробовал ничего подобного. Это интересная проблема!Ответы:
Каждый конечный автомат имеет своего рода обработчик событий и средства для запуска этих событий. Этот обработчик принимает в качестве входных данных существующее состояние и тип события, выбирает новое состояние и при необходимости запускает некоторый код побочного эффекта.
По сути, находясь в состоянии
B
, ваш основной обработчик событий пересылает любые события, которые он не распознает,B
обработчику событий и остается в состоянииB
. КогдаB
требуется перейти кC
, он отправляет соответствующее событие в основной обработчик событий.источник
Вы читали этот раздел Таупа ? Есть несколько различных способов сделать это, но многие из них зависят от того, как вы разбили свои конечные автоматы. Это отдельные процессы? Потоки? Объекты?
Выясните, как вы их построили, и посмотрите, есть ли для них канонический способ общения. Если его нет, возможно, вы неправильно проектируете свою систему.
Для меня я бы посмотрел на отдельные процессы, соединяя stdin и stdout вместе. Дочерний конечный автомат становится автономным, воздействуя на стандартный ввод и выводя на стандартный вывод. Это становится задачей родительского конечного автомата - запускать дочерний процесс, подключать каналы, а затем выгружать данные и ждать результатов. Все это уже сделано на всех современных языках, поэтому это должно быть легко сделать.
источник
Разделите два конечных автомата и используйте передачу сообщений между ними. Таким образом, конечный автомат 1 будет исходить из ABC, где в состоянии B он проверяет текущие результаты из конечного автомата 2. Если выходные данные изменились, конечный автомат 1 может учитывать его, и конечный автомат 2 не должен иметь никакой осведомленности о том, как конечный автомат 1 на самом деле работает. Что-то вроде:
источник
Решение зависит от того, 1) являются ли подсостояния A видимыми для подсостояний B. 2) Происходят ли AB и C из общего родителя. Если у них общий родитель и видимость универсальна, у вас не должно быть особых проблем при переходе из подсостояния B в подсостояние A.
Если вы изолировали их через пространства имен и / или A, B и C не имеют общего родителя, то лучше всего иметь внешний драйвер изменения состояния для машин A, B и C. Это можно сделать через обработчик событий. Просто найдите наблюдателя в A, который может прослушивать события, возникающие в B, и переходить в собственное подсостояние на основе события.
источник