Дилемма дизайна рабочего процесса - машина состояния, да или нет
Я новичок в WF, но я прочитал книгу и много сделал для игры в Google. Я хочу написать службу управления запасами. Реестр состоит из отдельных элементов, которые имеют состояние:
- Запасной
- Installed
- В-Ремонт
Элементы могут проводить месяцы в каждом состоянии, и есть тысячи элементов.
Вопрос в том, должен ли я создать рабочий процесс для конечных автоматов для всех разных состояний? Или я создаю рабочие процессы для перехода между состояниями?
Если я правильно понимаю, если я создаю рабочий процесс одного конечного автомата, всегда будет работать рабочий процесс для каждого элемента. Это означает, что тысячи непрерывных рабочих процессов. Кроме того, мне нужно иметь возможность отображать моментальный снимок состояния каждого элемента, поэтому это означает, что я должен как-то запросить все рабочие процессы для состояния, в котором они находятся в настоящее время, или иным образом сохраняться в базе данных после каждого перехода состояния.
Однако логический процесс состояния-машины логически звучит как правильная вещь, поэтому моя дилемма.
Пожалуйста, помогите мне, если вы можете: -)
Спасибо!
Update:
Предположим, что у меня больше состояний, чем выше 3, и что не все переходы состояний возможны.
Победитель Bounty: Maurice. Спасибо всем, кто действительно помог мне понять больше о рабочих процессах, фундаменте рабочего процесса MS и других более легких альтернативах. К сожалению, победитель может быть только один, и Морис отвечает вместе с его комментариями, которые мне больше всего помогли.
Ответы
Ответ 1
Не уверен, что рабочий процесс - это то, что вы ищете в первую очередь.
Рабочий процесс - это своего рода бизнес-процесс, который имеет место. Это подразумевает начало и конец процесса. Ваше описание больше похоже на то, что вы отслеживаете инвентаризацию сортов с элементами, находящимися в инвентаре.
Звук рабочего потока более подходит, когда элемент изменяет состояние. Например, когда элемент установлен и ломается, и его необходимо устранить, вы должны начать рабочий процесс, чтобы заменить деталь на рабочую, отправить исправленную часть, и, в конце концов, вернуть ее на склад в качестве фиксированного запасной. Рабочий процесс будет описывать этот процесс и начинаться с отчета об сломанном элементе и заканчиваться тем, что элемент был либо отремонтирован, либо отброшен и заменен.
Этот последний рабочий процесс может быть очень полезным, поскольку элемент проходит через различные этапы, например:
- Сломанный и установленный
- Сломанный и замененный
- В магазине для ремонта
- Капремонт
- и т.д.
Ответ 2
Конечный автомат - очень эффективный способ реализации, хотя я бы рекомендовал рассмотреть структуру под названием StateLess by Nicholas Blumhardt (создатель Autofaq), поскольку это удивительно простая реализация конечной машины, которая позволяет избежать ненужной сложности рабочего процесса Windows. Его подход позволяет избежать проблемы длительных рабочих процессов, выполняемых движком среды выполнения, поскольку состояние определяется простой переменной, такой как строка или int.
Вот пример конечного автомата:
var phoneCall = new StateMachine<State, Trigger>(State.OffHook);
phoneCall.Configure(State.OffHook)
.Permit(Trigger.CallDialed, State.Ringing);
phoneCall.Configure(State.Ringing)
.Permit(Trigger.HungUp, State.OffHook)
.Permit(Trigger.CallConnected, State.Connected);
phoneCall.Configure(State.Connected)
.OnEntry(() => StartCallTimer())
.OnExit(() => StopCallTimer())
.Permit(Trigger.LeftMessage, State.OffHook)
.Permit(Trigger.HungUp, State.OffHook)
.Permit(Trigger.PlacedOnHold, State.OnHold);
// ...
phoneCall.Fire(Trigger.CallDialled);
Assert.AreEqual(State.Ringing, phoneCall.State);
Ваше состояние может быть целым числом, которое позволит вам передать текущее состояние из базы данных. Это можно установить на конструкторе конечного автомата следующим образом:
var stateMachine = new StateMachine<State, Trigger>(
() => myState.Value,
s => myState.Value = s);
Вы можете реализовать это только в одной сборке, по сравнению с несколькими проектами, необходимыми для запуска рабочего процесса Windows. Техническое обслуживание крайне низкое, их нет "дизайнера", который генерирует код для вашего и т.д. Опять же, это просто, и там красота.
Ответ 3
Учитывая ваши дополнения (более трех состояний, не все переходы разрешены), я бы сделал следующее:
- Сохранять состояние каждого элемента в самом элементе.
Это можно сделать очень легко: добавьте участника в класс или столбец в таблицу и т.д., как другие, уже упомянутые в их сообщениях/комментариях.
- Используйте один конечный автомат (это может быть что угодно: от экземпляра класса до таблицы с законными переходами), который содержит вашу бизнес-логику, то есть разрешенные переходы между состояниями и знание о том, какие дополнительные действия выполнять, когда элемент изменяет свое состояние.
Все, что вам нужно сделать, это преобразовать ваши объекты с помощью конечного автомата, когда происходит событие extern, что заставляет/подразумевает именно это.
Ответ 4
ок. посмотрим, смогу ли я вам помочь. Начнем с дизайна:
имеет смысл создать конечный автомат и рабочий процесс. Оба являются просто разными взглядами на вашу проблему и пролить некоторый свет с другой точки зрения на нее. На самом деле часто случается, что разработчик, который является новым для рабочих процессов, проектирует машину состояний вместо процесса рабочего процесса. В представлении процесса рабочего процесса в основном переключаются роли ящиков и переходов на диаграмме: поле - это действие, которое может изменять состояние - при переходе, рабочий элемент может попасть в новое состояние (нормально, это нелогично правильно, но это может помочь: -)
Для меня кажется, что аспект государственной машины более важен. Поэтому реализуйте свое программное обеспечение как конечный автомат.
И да - вы должны сделать все элементы постоянными в базе данных. Это то, как вы также выполняете очень длинные рабочие процессы - они живут в базе данных, пока они не активируются какой-либо деятельностью. Это так, как все это делается с помощью систем управления бизнес-процессами (BPMS). Эти рабочие процессы НЕ хранятся в памяти.
Сохранение всего в базе данных упрощает создание отчетов.
Как уже упоминалось, создайте новый код с информацией о состоянии или даже создайте новую таблицу с метаданными: состояние, возможно, журнал, когда состояние изменилось, кто изменил состояние, информацию о предстоящих событиях (часть было заказано, но не доставлено - после того, сколько дней кто-нибудь проверит у поставщика, если доставка была утеряна?). Это даст вам возможность добавлять метаданные по мере необходимости, не затрагивая вашу базу данных деталей.
Надеюсь, что это поможет!
Ответ 5
Как обсуждалось в комментариях к исходному сообщению, у меня есть некоторые проблемы с использованием WF для этой конкретной проблемы вообще.
Предложение "Элементы могут проводить месяцы в каждом состоянии, а есть тысячи элементов" - это триггер для этого: я считаю, что рабочие процессы (моделируемые с помощью WF) должны быть короче. Хотя нет жесткого правила относительно того, как долго может существовать или должен существовать экземпляр WF, несколько месяцев или, может быть, даже лет, вызывает у меня исключение "вне пределов", особенно если это будет очень распространенное положение дел для тысяч предметов: -)
Причины использования WF в ваших комментариях звучат, но не затрагивают эту конкретную точку. Поэтому я бы посоветовал вам использовать более короткие, специализированные модели WF для вещей, которые происходят между состояниями товарных позиций, но не фиксировать состояние элемента в состоянии WF. Долговечные, редко измененные состояния более подходят для механизма базы данных, где люди ожидают, что они будут и где они легко сообщаются.
Ответ 6
Несмотря на то, что шаблон состояния-машины является технически правильным вариантом, существует также возможность создания последовательного рабочего процесса с одним гигантским циклом. В некоторых случаях это работает лучше и понятнее.
Ответ 7
У вас есть три разных состояния, и, насколько я вижу, все переходы разрешены. Учитывая это, я бы не стал беспокоиться о машине состояния в смысле части кода, которая проверяет разрешенные переходы и делает движение вперед.
Государственные машины имеют смысл, когда государства управляют бизнесом или когда должен быть доверенный единственный фрагмент кода, который является единственным действующим лицом, ответственным за "проверенный переход".
Проще говоря, вам просто нужны сущности с заданным состоянием в любой момент времени...
Ответ 8
Aviad, я согласен с вашим комментарием в том, что рабочий процесс должен быть между состояниями. Состояние частей, которые инвентаризируются, звучит как статус/свойство элемента. Этот статус может быть сохранен практически любым способом (например, база данных, файл...), поскольку перемещение элемента между состояниями будет осуществляться на уровне бизнес-логики.
Похоже на забавный проект, удачи.
Ответ 9
Думаю, нам нужно понять пару вещей здесь.
State Machines - сосредоточится на представлении определенного состояния, в котором находится ваша организация.
WorkFlow - Определит процессы, которые вы выполняете для перемещения вашего объекта из исходного состояния в конечное.
В вашем случае, когда ваш общий процесс вращается вокруг одного объекта, и его текущее состояние в любой момент времени является одиночным, я бы рекомендовал перейти на конечный автомат.
Рекомендация:
Apache Commons SCXML обеспечивает легкий, встроенный механизм машинного процесса, который можно легко настроить и настроить во время выполнения в вашем приложении.
Ключевые моменты здесь вы должны определить свой scxml таким образом, чтобы между переходами состояния вашей сущности - вы можете указать рабочие процессы, которые вы хотите выполнить, с помощью "действий" или "слушателей".
ПРОГРАММА ОБРАЗЦОВ:
https://www.javacodegeeks.com/2012/06/apache-commons-scxml-finite-state.html
БОЛЬШЕ ОБ ОБЩЕНИИ SCXML 2.0
https://events.linuxfoundation.org/sites/events/files/slides/ApacheConUS2014%20-%20Apache%20Commons%20SCXML%202.0.pdf