четверг, 9 августа 2012 г.

Ruby и таблицы решений


Сегодня создавал интерфейс для редактора настроек для сканера данных котла.

    Так как СКАДА поддерживает древовидные параметры, то нужен был редактор OPC параметров. Для каждого объекта опроса есть каналы. В каждом канале есть параметры.

   Это была предыстория. Сама история интереснее. Для управления этими тремя списками  сделал один комплект кнопок (благо команды похожие) и стал динамически создавать редактор для текущего выделенного списка.

   Но возникла проблема: для управления состоянием (активно/заблокировано) кнопками, редактором и списками пришлось бы много писать условий и многие были бы похожи. Поэтому было решено прибегнуть к старому проверенному способу - таблицам решения.

  Саму таблицу решений вида:



можно было задать простым хешем. Но такое решение не масштабируемо, да и требует много спагетти-кода. Поэтому было решено создать класс с DSL для описания таблиц решения.

Воспользовался тем, что в рубине можно задавать массивы слов через %w| | и символы как is_editing: создал код:

question :is_editing do
   is_editing?
end

action :enable_add_btn do
   @add_btn.enable
end

condition is_editing:          %w| + - |
decision enable_add_btn:  %w| -  x |

Так как был использован WxRuby, то пришлось писать решения для запрешения.

И всё бы хорошо, но в таблицах решения количество пермутаций растёт в геометрической прогрессии с коэффициентом 2. У меня было использовано лишь 4 состояния, но пришлось
расписывать 16 состояний и для каждого состояния описывать активность кнопок, редакторов, списков.

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

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


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







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