воскресенье, 4 января 2009 г.

Begin

Что вы делаете, когда вся логика разрабатываемого класса крутится вокруг его состояния? К примеру, разрабатываем мы web магазин. Есть у нас сущность Order (заказ), ее создает «покупатель», затем он ставится в очередь на обработку, затем «оператор» формирует заказ и передает его «курьеру» для доставки, «курьер» доставляет заказ и делает отметку о доставке. Покупатель может редактировать все поля заказа, пока не передаст его на исполнение. После этого покупатель не может редактировать заказ, но может отозвать его, но только если заказ еще не передан для доставки. Оператор не может редактировать заказ, но может оповестить покупателя о задержке в связи с отсутствием товара на складе. Курьер может только проставлять отметку о доставке и только на тех заказах, что переданы для доставки ему. Ну и т.д. (много деталей опущено).

Довольно типичная картина, не правда ли? Действия доступные пользователям зависят от их роли и текущего состояния сущности, причем все эти особенности и детали способны утомить еще при чтении требований, не говоря уж о реализации. И в тоже время они являются весьма важными с точки зрения заказчика. А при реализации они размазываются тонким ровным слоем по всей бизнес логике и по UI в придачу. Ситуацию усугубляет то что, все эти требования очень волатильны, то есть склонны к частым и непредсказуемым изменениям. И вот он – живой кошмар любого разработчика перед нами во всей красе.
Однако с подобными задачами довольно просто можно справиться на основе workflow подходов, и в частности, с помошью конечного автомата или Finite State Machine.
Основная идея состоит в том, чтобы описать диаграмму состояний сущности (в нашем случае заказа), и допустимых переходов, при этом связав их с ролями пользователей.
Обычно, говоря о методе конечных автоматов, подразумевают создание класса, реализующего конкретную диаграмму. Но в нашем случае интереснее использовать иной подход, который менее распространен. Нам интереснее создать класс, способный исполнять любую диаграмму состояний, по воздействию внешних событий. При этом список переходов, доступных в данном состоянии для данного пользователя, на уровне UI представляется в виде набора доступных действий. А выбор любого из этих действий, вызывает выполнение соответствующего перехода в диаграмме состояний, и выполнение связанной с ним бизнес логики.

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

Что должен уметь делать этом framework? Он должен:
- описывать диаграммы состояний объектов, включающие перечень возможных состояний объекта, и возможные переходы между состояниями
- определять бизнес логику, выполняющуюся при изменении состояния объектов
- определять доступность переходов на основе ролей пользователей
- определять шаблоны оповещения при изменении состояния объекта и правила адресации на основе ролей пользователей
- переводить объекты из одного состояния в другое на основе описанных правил
- определять права доступа к атрибутам объекта в зависимости от состояния и роли пользователя

И в тоже время он не должен:
- зависеть от способов хранения бизнес-сущностей
- предъявлять какие либо требования к реализации классов бизнес-сущностей
- зависеть от UI библиотек (ASP.NET, WinForms)
- зависеть от провайдеров role-based security
- требовать наличия собственной БД для хранения своих настроек и состояния

Ничего готового на платформе .Net не обнаружилось. Windows Workflow не подошел на эту роль по причине своей монструозности (посмотрите список чего «не должен» делать движок и вам все станет понятно). Поэтому появилась мысль сделать свой движок, обобщив в нем свой многолетний опыт в данной области.
И вот в первом приближении такой движок готов. Называется он Listma, что значит Linking State Machine, или Подключаемая машина состояний, что вполне отражает его суть.
Listma - это проект с открытым исходным кодом. Хостится он будет на Google Code.

Все необходимые ссылки можно увидеть справа на сайдбаре.

Комментариев нет:

Отправить комментарий