Я уже несколько дней голову ломаю никак не получается придумать вариант реализации бизнес-логики.
Итак, есть BL, состоит из ~20 пунктов, каждый пункт состоит из ещё ~10 подпунктов.
Отмечу, что данная BL описывает use case регистрацию нашего приложения с мобильного устройства к нашему сервису.
Описание примерно такое:
Приложение шлёт следующие параметры:
список параметров, типов, флагов обязательности
Система проверяет полученную информацию по следующим правилам:
а. Требуемые параметры заданы
б. Параметр А валиден и существуют в системе соответствующие этому параметру сущности (D, E, L, M).
в. Параметр B соответствует множеству вариантов свойства C у сущности D.
г. Свойство F сущности E не превышает значение свойства G у сущности D.
д. ... куча подобных проверок
Система отсылает некий промежуточный ответ (если соответствующий флаг H1 определён в сущности D)
а. (Если флаг H2 определён в сущности D и свойство J сущности E == 1) или флаг H3 определён в сущности D ; система посылает сформированный промежуточный ответ
Получаем ответ от приложения и валидируем его
... несколько пунктов спустя
система создаёт объект сущности K и связывает его с сущностью E
а. свойство P1 сущности K =
I. L.P2 + E.P3 если L.P4 = 5
II. L.P2 + (E.P3 * CFG1 /100) если L.P5 = 10 И M.P6 = 1
...
система меняет свойство E.J в 1 если E.J == 0
...
система сохраняет сущность K в системе и отправляет сущность K устройству
По дурацки описал, к сожалению по NDA не могу привести конкретные данные, но масштаб бедствия думаю, что понятен.
Наши тестировщики по данному кейсу регистрации описали > 100 тест-кейсов.
Я попробовал прототип сделать, получился код лапшой. Попробовал разбить на кучу мелких классов — запутался во всех этих свойствах, кто что когда должен менять.
Посмотрел как в исходном коде MS Unity используются стратегии и политики через некий pipe, получил кучу стратегий которые берут данные из политик и как-то работают. Но совершенно потерялась наглядность и не понятно кто как и какие политики должен задавать.
Сейчас подумываю в сторону Windows Workflow Foundation.
Был бы очень рад, если бы подсказали идею как это можно реализовать и как это можно описать (UML диаграммы?) чтобы другие программисты видели те же самые требования, но уже ближе к реализации (в требованиях нет деталей реализации, поэтому 2 слова в требованиях могут раскрываться в 2 таблицы в БД и кучу кода).
Здравствуйте, Аноним, Вы писали:
А>Я уже несколько дней голову ломаю никак не получается придумать вариант реализации бизнес-логики. А>Итак, есть BL, состоит из ~20 пунктов, каждый пункт состоит из ещё ~10 подпунктов. А>Отмечу, что данная BL описывает use case регистрацию нашего приложения с мобильного устройства к нашему сервису.
Я насколько понял, Ваш девайс делает несколько различных вызовов сервиса, каждый из которых может завершиться неуспешно по множеству причин, между вызовами может проходить значительное время, но в результате на сервере должен образоваться некий законченный набор данных об устройстве.
Если так, то это типичный кейс применения паттерна "сага". Сага — это машина состояний, конечный автомат (скорее даже так: в методологии SOA для паттерна "конечный автомат" зачем-то придумали отдельное название "сага" ). У саги есть внутреннее состояние (обычно хранится в персистентном хранилище, но необязательно) и есть обработчики входящих событий, которые это состояние могут менять. В Вашем случае события — это вызовы методов сервиса девайсом.
Логика переходов саги между состояниями очень удобно описывается диаграммой состояний. Логика обработчиков событий — (например) диаграммой последовательности. Типичный алгоритм обработки очередного вызова от девайса может выглядеть так:
Если КусокДанныхN еще не сохранен, то:
Провалидировать КусокДанныхN
Если КусокДанныхN невалиден, то:
Кинуть исключение (девайс получит ошибку)
Сохранить КусокДанныхN
Перевести сагу в состояние _КусокДанныхNСохранен_
Здравствуйте, Аноним, Вы писали:
А>Я попробовал прототип сделать, получился код лапшой. Попробовал разбить на кучу мелких классов — запутался во всех этих свойствах, кто что когда должен менять.
Выбрать средний вариант: меньше классов, использовать паттерны.
Re[2]: Как спроектировать бизнес-логику
От:
Аноним
Дата:
26.01.14 05:27
Оценка:
Здравствуйте, scale_tone, Вы писали:
_>Я насколько понял, Ваш девайс делает несколько различных вызовов сервиса, каждый из которых может завершиться неуспешно по множеству причин, между вызовами может проходить значительное время, но в результате на сервере должен образоваться некий законченный набор данных об устройстве.
Спасибо за ответ!
Я ввёл в заблуждение своим описанием. На самом деле регистрация происходит за 1, максимум 2 обращения и это всё происходит достаточно быстро (в течении минуты). Т.е. основная проблема именно в большом количестве условий, которые приводят к установке большого количества свойств у разных сущностей. Но, вроде, всё равно можно описать как конечный автомат. Я попробую с "сагой" поэкспериментировать. Ещё раз спасибо за идею!
Re[2]: Как спроектировать бизнес-логику
От:
Аноним
Дата:
26.01.14 05:33
Оценка:
Здравствуйте, Rinbe, Вы писали:
R>Выбрать средний вариант: меньше классов, использовать паттерны.
День добрый!
Вопрос как раз в том, какие паттерны тут могут помочь?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Rinbe, Вы писали:
R>>Выбрать средний вариант: меньше классов, использовать паттерны. А>День добрый! А>Вопрос как раз в том, какие паттерны тут могут помочь?
State,strategy,template method.
A>Т.е. основная проблема именно в большом количестве условий, которые приводят к установке большого количества свойств у разных сущностей.
Странная регистрация. Почему бы просто не сделать базовый класс для всех типов регистрации, а от него наследовать конкретные типы регистрации?
Здравствуйте, Аноним, Вы писали:
А>Спасибо.
1. Используй абстракции уровня выше чем пишешь сейчас для описания прецедентов.
2. Построй диаграмму последовательности для каждго прецедента.
Здравствуйте, Аноним, Вы писали:
А>Описание примерно такое:
overdetailed в чистом виде: в ТЗ смешаны требования протокола, детали реализации и диаграмма состояний.
Решается, как всегда, поеданием слона по кусочкам:
1. Расписываем процесс регистрации в крупную клетку:
* Подача запроса на регистрацию
* Валидация запроса (с циклом для получения дополнительных данных)
* магия с K~E=L.P2+E.P3@$#^%^&*()_ (Как я понял, это был собственно процесс регистрации)
2. Определяемся с форматом передачи данных — или это будет одна и та же структура для всех этапов, или разные. Если разные — расписываем преобразования между каждым из этапов.
3. Расписываем каждый этап отдельно, по необходимости — разбиваем на подэтапы.
4. Ни в коем случае не добавляем связи между подэтапами разных этапов. Грубо говоря "Запрашиваем пару ключей в п.3.1 для использования в 4.6.22" надо превратить в "Заполнение предусловий для п.4. 3.1 запрашиваем пару ключей. 3.2 ..."
Повторять до завершения.
Важно! При реализации нужно проверять все относящиеся к состоянию условия ассертами. В отличие от тестов, ассерты работают всегда, а не только в тепличных условиях "ограниченный набор на входе, ограниченный на выходе" и позволяют отловить ситуации "внешне всё ок, внутри бардак". Для всяких сложных процессов/протоколов без таких проверок никуда.
Прелесть этой схемы в том, что в каждый отдельно взятый момент не требуется держать в голове все детали, достаточно общей картины и требований для конкретного куска.
Как следствие — функционал превосходно разбирается на итерации, от "Hello world" и до готового решения, ну и с тестированием/сопровождением тоже не будет особых проблем.
Re[2]: Как спроектировать бизнес-логику
От:
Аноним
Дата:
31.01.14 20:42
Оценка:
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, Аноним, Вы писали:
S>Решается, как всегда, поеданием слона по кусочкам:
S>1. Расписываем процесс регистрации в крупную клетку: S>* Подача запроса на регистрацию S>* Валидация запроса (с циклом для получения дополнительных данных) S>* магия с K~E=L.P2+E.P3@$#^%^&*()_ (Как я понял, это был собственно процесс регистрации)
Спасибо за ответ!
Я правильно понимаю, что ваш вариант сильно перекликается с предложением scale_tone об использовании паттерна "Сага", т.е. конечного автомата?
Просто толковые люди советуют вещи, я боюсь не так понять
Здравствуйте, Аноним, Вы писали:
А>Я правильно понимаю, что ваш вариант сильно перекликается с предложением scale_tone об использовании паттерна "Сага", т.е. конечного автомата? А>Просто толковые люди советуют вещи, я боюсь не так понять
scale_tone может посчитает иначе, на мой взгляд — советы не пересекаются. Я предпочитаю идти последовательно — определили проблему, разбили на части, для каждого отдельного куска нашли подходящее решение.
У ув. scale_tone — уже готовое решение, насколько оно подойдёт к проблеме и к используемым инструментам — , это только вам решать