Отслеживание состояний объекта - SOS - PullRequest
0 голосов
/ 27 мая 2009

Привет, мудрые люди в ТАК. Это SOS.

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

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

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

Я создал несколько статических классов / методов, которые возвращают массивы разрешенных действий в зависимости от состояния запроса. Существует около 20 состояний, в которых может находиться приложение. Я позаботился на основе состояния, чтобы удалить / отключить ссылки для действий, которые невозможны в этом состоянии. Теперь возникает проблема: предположим, что запрос находится в состоянии X.

Теперь, если в прошлом действие l было предпринято по запросу, мы не можем разрешить l или на основании этого некоторые произвольные действия m, n, o.

После написания всех методов для получения массивов ссылок для 20 состояний я должен отфильтровать массивы на основе прошлой истории действий (которая хранится в sql db), что является очень и очень большой задачей.

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

Ответы [ 3 ]

1 голос
/ 29 мая 2009

Как я понимаю, у вас есть сценарий реального рабочего процесса. В этом случае я бы:

  1. Смоделируйте все состояние как один объект, если это возможно (одна строка с фиксированным числом полей). Я не стал бы моделировать это как набор действий.

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

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

  4. Имея состояние, смоделированное как одна строка, я бы реализовал независимые предикаты для разрешения действия.

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

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

0 голосов
/ 27 мая 2009

Первое, что пришло мне в голову: Statemachine. Каждое государство является своего рода объектом. У всех состояний есть некоторый метод "processRequest", который переводит выполнение в следующее состояние.

Второе, что пришло мне в голову - эти состояния должны быть организованы как дерево или граф. График представляет историю запросов. Вы начинаете в исходном состоянии. Вы получаете запрос A, переходите в состояние A. После этого вы получаете запрос B, переходите к AB. Состояние воды AB равно BA, не понятно по вашему описанию.

Таким образом, вы получаете гораздо больше состояний, чем ваши 20 состояний, которые у вас есть сейчас, но каждое состояние включает в себя историю. Я бы предложил соглашение об именах после пути, по которому вы должны были идти (как AB раньше). И, возможно, вы можете повторно использовать состояния A и B в AB, чтобы минимизировать кодирование.

0 голосов
/ 27 мая 2009

Похоже на работу для конечного автомата или на несколько гигантских вложенных переключателей (которые вы когда-либо предпочитаете).

...