Управление состоянием формы через конечный автомат

Программирование - Практика программирования

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

Оглавление

ВВЕДЕНИЕ

ФУНКЦИЯ СОСТОЯНИЯ

ПАРАМЕТРИЗАЦИЯ СОСТОЯНИЙ

ПОДСИСТЕМА "УПРАВЛЕНИЕ ФОРМОЙ"

Инициализация

Обработчик события "ПриИзменении"

Параметры состояния

Функции состояния

Процедуры подсистемы. API

Структура данных

Производительность

ПРАКТИЧЕСКИЕ ПРИМЕРЫ

Общая демонстрация. Стенд "УправлениеФормой"

Управление доступностью. Исключение из общего режима "Только просмотр"

Управление видимостью. Стенд "Валютный платеж"

Установка пометки. Стенд "Включение панелей"

Оформление заголовков. Стенд "Гиперссылка"

ПОСТАВКА


Введение

Любая форма, даже самая простая, содержит в себе элементы. Если в форме предусмотрено несколько состояний, то каждое из них должно поддерживаться соответствующими состояниями её элементов.

Запрограммировать элементы для всех состояний формы может оказаться нетривиальной задачей. Дело в том, что количество состояний формы может исчисляться десятками (см. Формулу 1. числа состояний n элементов по k состояниям) и необходимость предусмотреть их большое количество приводит к созданию запутанных и сложных алгоритмов перехода.

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

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

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

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

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

Использование функционального подхода для определения свойств элементов может показаться очень расточительным. Однако основные потери при этом не в производительности (дополнительные потери здесь возникают на сам вызов функции, но это во первых очень незначительное время, во вторых поддается оптимизации путем использования вызова только по изменениям), а в объеме кода. Но кого особо волнует объём кода в современном мире ПО? Особенно если сам код получается путем генерации по декларативному описанию. Нельзя забывать и о том, что элементы можно группировать и применять функцию к группе - тогда количество таких функций будет меньше.

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

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

При непрямом расчете параметра используется функция значения. Результатом работы функции является новое значение параметра.

Инициализация данных подсистемы производится в процедуре модуля формы ПриСозданииНаСервере. В процедуре создается структура данных состояния формы. Декларативное описание параметров и настроек элементов формы производится через вызов соответствующих процедур: ДобавитьПараметр, ДобавитьНастройку.

В завершение, с помощью процедуры ДобавитьРеквизитФормыДанныеУправленияФормой создается реквизит формы, в котором сохраняется структура данных настройки состояния. В процедуре ДобавитьОбработчикиПриИзменении происходит установка обработчика в элементах формы, с которыми есть связь параметра с элементом через общие данные.

Листинг 1. Настройка параметров управления формой при создании формы

 

Параметры состояния могут зависеть либо напрямую от данных, либо вычисляться на основе параметров, которые в конечном счете ссылаются на данные.

Обработка события ПриИзменении позволяет в момент изменения данных также обновлять данные параметров состояния. Далее при настройке элементов формы для нового состояния подсистема анализирует изменения параметров и по списку измененных определяет список зависимых от измененных параметров элементов формы. Полученный список элементов приводится к текущему состоянию.

Параметры состояния

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

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

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

Листинг 2. Пример реализации функции значения

 

Основное назначение функции состояния - определять свойства элемента по значениям параметров. Функция вызывается для тех элементов, состояние которых зависит от измененных параметров.

Функция может возвращать значение. Практически анализируется только одно значение - если возвращено Ложь, то обновление состояния элемента не происходит. Практическое применение возвращаемого значения я пока не нашел, однако заменить функцию на процедуру тоже нельзя. Последнее связано с ограничением платформы: для вычисления функции используется оператор Вычислить, а для процедуры - Выполнить. Первый работает везде, а второй только в толстом и тонком клиенте (не работает в веб-клиенте, на iOS). И кроме того, функцию можно отлаживать в отличии от кода в операторе Выполнить.

Листинг 3. Пример реализации функции состояния


Процедуры подсистемы

Процедуры и функции подсистемы представлены в таблице API ниже. Более подробное описание содержится в самих модулях (для описания используется формат по стандартам 1С).

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

Таблица 1. API

Модуль Функция/процедура
Модуль формы УправлениеФормой
НастройкаЭлементовФормы
РассчитатьЗначенияПараметров
РассчитатьЗначениеПараметра
УправлениеФормойКлиентСервер ПолучитьСтруктуруДанныхУправленияФормой
ПолучитьСтруктуруПараметра
ДобавитьПараметр
ПолучитьСтруктуруНастройки
ДобавитьНастройку
УправлениеФормой ДобавитьРеквизитФормыДанныеУправленияФормой
ДобавитьОбработчикиПриИзменении

 

Рисунок 1. Диаграмма взаимодействия

 

Структура данных

В подсистеме используется два основных элемента данных: элементы и параметры состояния и два вспомогательных - зависимые от параметров элементы и зависимые от параметров параметры.

Статичные данные заполняются в момент создания формы и сохраняются в фиксированной структуре в реквизите формы ДанныеУправленияФормой. Значения параметров состояния запоминаются в таблице реквизита формы ЗначенияПараметровСостояния.

Рисунок 2. ER-диаграмма

 

 

Рисунок 3. Объектная модель данных

 

Исследование производительности показало, что в рамках одного контекста исполнения (сервер или клиент) различия в производительности при расчете элементов формы определяются самыми длительными операциями: например, операция получения дополнительных реквизитов объекта. В тоже время, благодаря механизму расчета по изменениям, показатели производительности остаются очень высокими и определяются временем исполнения отдельных функций состояния.

Для тестирования производительности в форме обработки стенда достаточно убрать параметр ИзмененныеРеквизиты при вызове процедуры УправлениеФормой. Такой вызов приведет к полному расчету формы при каждом изменении. Измерять нужно вызов процедуры УправлениеФормой.

Практические примеры

Общая демонстрация. Стенд "УправлениеФормой"

В качестве иллюстрации проблематики и механизма работы формы я разработал обработку-стенд. Форма обработки содержит 12 реквизитов. Состояние формы описывается 4 параметрами. Если для простоты считать, что параметры могут принимать всего два значения, то общее число состояний формы согласно формуле сочетаний k из n будет 70. Однако из числа возможных сочетаний я выбрал всего 14 доступных. Эти состояния представлены в таблице ниже.

Приведенные расчеты показывают, как быстро растет число возможных состояний (при количестве значений параметров 12 число состояний уже будет около 500). С другой стороны не все состояния имеют смысл и это спасает ситуацию с программированием этих состояний. Однако при достаточно сложном программном коде можно «легко» не уследить и тогда число недокументированных доступных состояний может резко возрасти.

Формула 1. Число сочетаний k из n

 

Формула 2. Число сочетаний 4 из 8

 

Рисунок 4. Форма стенда в различный состояниях

 

Таблица 1. Состояния формы

 

Управление доступностью. Исключение из общего режима "Только просмотр"

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

Для реализации описанного поведения такие элементы нужно отвязать от реквизитов объекта данных и сбросить признак «Сохранение данных». Именно при такой настройке платформа не будет распространять признак "Только просмотр", установленный для формы, на элементы исключения.

Для управления признаком "Только просмотр" для таких элементов нужно добавить их настройку в подсистему "Управление формой". Порядок внедрения подсистемы рассмотрим на примере доработки документа _ДемоПеремещениеТоваров из демо-базы БСП. Добавим реквизит формы Комментарий и элемент-поле редактирования реквизита с таким же именем - Комментарий. Далее выполним следующие шаги:

  1. Скопируем в форму документа функции области ПроцедурыПодсистемыУправлениеФормой из формы демо-обработки стенда
  2. Добавим настройку параметров в процедуре ПриСозданииНаСервере
  3. Добавим функцию состояния элемента формы Комментарий

Листинг 4. Модуль формы доработанного документа. Где область КодБСП содержит код из демо-базы БСП, а функция состояния здесь одна - РассчитатьСвойстваЭлементаКомментарий.

 

Управление видимостью. Стенд "Валютный платеж"

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

Рисунок 5. 

Листинг 5.

Установка пометки. Стенд "Включение панелей"

В стенде демонстрируется настройка включения видимостей групп элементов и изменение состояния пометки кнопок командной панели.

Рисунок 6.

Листинг 6.

 

Оформление заголовков. Стенд "Гиперссылка"

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

Рисунок 7.

Листинг 7.


Поставка

Решение поставляется в виде конфигурации и обработок демо-стендов. Подсистема использует общие процедуры БСП. Перед объединением сбросьте признак объединять свойства конфигурации.

Для использования демо-обработок разверните демо-базу БСП и объедините с конфигурацией подсистемы.

Порядок использования в своих формах:

  1. Из демо-стенда скопируйте в модуль формы область ПроцедурыПодсистемыУправлениеФормой
  2. Создайте область ФункцииСостоянияИЗначения и добавьте свои функции состояния и значения параметров
  3. Добавьте настройку данных управления формой в процедуре ПриСозданииНаСервере

 

Таблица 2. Состав поставки

Метаданные Наименование Назначение Ограничения
ОбщийМодуль УправлениеФормой   Использует БСП
  УправлениеФормойКлиентСервер   Использует БСП
  ОбщийКлиентСервер вспомогательный  
  ОбщийВызовСервера вспомогательный  
Обработка СтендУправлениеФормой демо  
  СтендВключениеПанелей демо  
   СтендРасчетВВалюте демо  
  СтендЗаголовокГиперссылки демо  

 

76

Скачать файлы

Наименование Файл Версия Размер
Конфигурация+демо-обработки
.zip 49,22Kb
17.06.18
7
.zip 1.02 49,22Kb 7 Скачать

См. также

Комментарии
Сортировка: Древо
1. bulpi 130 19.06.18 12:10 Сейчас в теме
"Но кого особо волнует объём кода в современном мире ПО?"
Меня волнует, меня. Когда мне нужно что-то переделывать в конфигурациях, написанных такими умниками.
Грибоедов , "Горе от ума". Мне всегда вспоминается это гениальное название, когда я читаю подобные вещи.
Solovyeff; oninfostart; Yakud3a; Soloist; корум; rpgshnik; grumagargler; SlavaKron; +8 Ответить
9. kalyaka 392 19.06.18 18:42 Сейчас в теме
(1) Извините, ответ получился в отдельный пост ниже
2. kalyaka 392 19.06.18 12:31 Сейчас в теме
Не зная системы понять ее по фрагментам может быть очень тяжело и наоборот - знание системы позволяет реализовывать качественные системы с более сложным поведением.

Если в качестве аналогии взять технологию Конвертации, то при описании правил на выходе тоже генерируется код. И наверняка, если писать код обмена без правил его объем будет меньше, однако это ж не говорит в пользу такого подхода?
3. Идальго 89 19.06.18 14:00 Сейчас в теме
Думаю, что вот излишне формы лучше не усложнять, таких вот обработчиков состояний стараться не городить шибко много. Муторно поддерживать всё это, особенно когда разные люди и каждый на свой лад (и в разных местах) пишут такие штуки. А в целом норм написано вроде.
Solovyeff; Gang031; rpgshnik; bulpi; CSiER; +5 Ответить
8. kalyaka 392 19.06.18 18:39 Сейчас в теме
(3) Согласен, поэтому планирую модуль формы генерировать на основе декларативного описания по аналогии получения модуля обмена из Конвертации данных
4. unichkin 1008 19.06.18 17:34 Сейчас в теме
Модули форм не оформлены по стандарту. Нет областей основных разделов. Кроме того, для параметризованной передачи используется ЭтаФорма, а не ЭтотОбъект. Далее в внеконтекстных методах формы - используется параметр "ЭтаФорма". Понятно что эта переменная вне контекста не является именно свойством, а это переданный параметр. Но все-равно, кажется что нужно выделить этот нюанс, который при разработке может создать лишнюю "кашу в голове" - я в таких случаях именую параметр просто "Форма". Пример:
&НаКлиентеНаСервереБезКонтекста
Функция ПроцентСкидки(Форма)
    Если Форма.Объект.Статус = ПредопределенноеЗначение(...)    
    //...

КонецФункции

// Вызов
Если ПроцентСкидки(ЭтотОбъект) > 0 Тогда
//...

Показать


Подобный пример можно увидеть на ИТС https://its.1c.ru/db/v8std/content/2149184279/hdoc
21. kalyaka 392 20.06.18 20:40 Сейчас в теме
(4) Согласен. По началу я так и писал. Однако при разработке системы удобнее использовать имя ЭтаФорма, т.к. В этом случае работает контекстная подсказка. После разработки глаз «замылился» и мне уже казалось вполне обычно использование ЭтаФорма как параметр.

Про оформление областей разделов узнал для себя новое. Сами разделы то появились относительно недавно.

В приведенных модулях форм демо-обработок нет смысла выделять разделы, т.к. Сами обработки - пустышки, назначение которых пояснить работу механизма.
24. unichkin 1008 21.06.18 00:04 Сейчас в теме
(21)
В приведенных модулях форм демо-обработок нет смысла выделять разделы, т.к. Сами обработки - пустышки, назначение которых пояснить работу механизма.

Коль выкладывается встраиваемая подсистема, с примерами - я считаю что "нет смысла" так рассуждать :) Это т.н. хороший тон. А то выходит - вот это я оформлю, а вот здесь - можно и забить.
Беда в том, что те кто только начинает постигать 1С - учась и смотря на такие примеры вообще опускают оформление в 99% случаев. А вместе с ним - и прочие стандарты ИТС. Дьявол в деталях..
pavlov_dv; +1 Ответить
27. kalyaka 392 21.06.18 23:34 Сейчас в теме
(24) Тут я сторонник рационального перфекционизма. Что касается непосредственно подсистемы должно быть на самом высоком уровне, т.к. это основа.

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

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

Идея должна либо умереть, либо превратиться в практику. Это как с новым изобретением. Вначале собираются устройство образно на "соплях". Демонстрируют и убеждают вложиться. После, как говорят, идея должна преодолеть пустыню смерти.
5. unichkin 1008 19.06.18 17:54 Сейчас в теме
Общие модули подсистемы также не оформлены, нарушены рекомендации итс по именованию методов https://its.1c.ru/db/v8std#content:2149184296:hdoc. Присутствуют избыточные судя по коду модули "ОбщийВызовСервера", "ОбщийКлиентСервер" - также не оформленные. Флаги серверного модуля "УправлениеФормой" - выставлены некорректно с т.з. стандарта https://its.1c.ru/db/v8std#content:2149184118:hdoc.
Идея хорошая, но я б себе это внедрять не стал. Либо после доработки. А там, вероятно родился иной архитектурный концепт.
22. kalyaka 392 20.06.18 20:48 Сейчас в теме
(5) про общие модули «ОбщийВызовСервера», «ОбщийКлиентСервер». Не знал, что они вообще кого то привлекут внимание. Дело в том, что эти модули я использую во многих разработках и не только я.

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

А вот про «УправлениеФормой» -Согласен, для серверного модуля нужно ставить Внешнее соединение и Клиент (обычное приложение), это я не доглядел. Спасибо :)
25. unichkin 1008 21.06.18 00:06 Сейчас в теме
(22)
Конкретно в этом решении из модуля используется две простые функции, одна в подсистеме и одна в демо-обработке, т.е. Использование их вообще не принципиально.

Получается, я при встраивании должен об этом думать?.. И где-же универсальность?
28. kalyaka 392 21.06.18 23:36 Сейчас в теме
(25) Продукт еще не полный, пока просто зацените идею :)
6. grumagargler 425 19.06.18 18:02 Сейчас в теме
подскажите пожалуйста, а если у поля свой обработчик ПриИзменении, что в этом случае предлагает подход?
yarohagolovatiy; +1 Ответить
7. kalyaka 392 19.06.18 18:24 Сейчас в теме
(6) в этом случае Вы сами ответственны за вызов процедуры УправлениеФормой, подсистема не перекрывает уже установленные обработчики.

Думаю это нормально: система обеспечивает обработчик по умолчанию, а если поведение по умолчанию Вам не подходит, то Вы пишите свой обработчик.
10. grumagargler 425 19.06.18 18:47 Сейчас в теме
(7) ясно. Выскажусь как разработчик похожего механизма: вы уделили большое внимание теории, оставив без должного внимания практику. В подавляющем большинстве случаев, видимость/доступность связана не только с действием пользователя, но и программной обработкой и события, напрямую с этим не связанным, например при перечтении данных формы; наличие вызова обновления из таких обработчиков - делает несостоятельной всю описываемую теорию, потому что она ложится на плечи программиста. Значительно проще сериализовать неподдерживаемое условное оформление формы (включая условия СКД) в реквизит формы, дав программисту в руки безконтекстную клиент/серверную функцию обновления по зависимому реквизиту или обновляемому контролу.
yarohagolovatiy; +1 Ответить
11. Adept 19.06.18 19:11 Сейчас в теме
(10) Может не внимательно смотрел, вы выкладывали этот механизм в свободный доступ? Хотелось бы посмотреть ...
12. grumagargler 425 19.06.18 19:23 Сейчас в теме
(11) Реализация выполнена в рамках решения Тестер. Но, Александр, это решение внутри на английском, по собственным стандартам, и вероятно будет совсем вам не интересно. На всякий случай: за это там отвечают два модуля: Appearance и AppearanceSrv, а пример использования см. в основной форме справочника Scenarios (https://github.com/grumagargler/tester)
13. grumagargler 425 19.06.18 19:40 Сейчас в теме
(11) (непонятно почему пропало измененное сообщение) Реализация выполнена в рамках решения Тестер. Но, Александр, это решение внутри на английском, по собственным стандартам, и вероятно будет совсем вам не интересно. На всякий случай: за это там отвечают два модуля: Appearance и AppearanceSrv, а пример использования см. в основной форме справочника Scenarios (https://github.com/grumagargler/tester)
14. kalyaka 392 19.06.18 20:33 Сейчас в теме
(10) Теория рождается из обобщения практики. Другое дело, что вначале модель может быть слишком идеальной.
Следующей своей задачей вижу проверить теорию на практике и при необходимости доработать реализацию.

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

Если же имеется в виду работа с моделью в терминологии MVC, то для этого у меня есть другое решение.

В Вашем примере при перечтении данных формы я так понимаю нужно полностью пересчитать её состояние - это достигается вызовом процедуры УправлениеФормой без указания источника изменений. В этом случае читается, что изменились все параметры состояния. И тот факт, что система сама не может «догадаться» пересчитаться при внешних событиях (требуется программировать эти случаи) делает несостоятельным предложенное решение?

По поводу использования условного оформления идея интересная. Вы писали о разработке похожего механизма, было бы интересно ознакомиться.
yarohagolovatiy; +1 Ответить
15. grumagargler 425 19.06.18 21:21 Сейчас в теме
(14)
делает несостоятельным предложенное решение?

Спасибо за содержательный комментарий. Но я смею утверждать, что да, подход не выдерживает испытание практикой. Понимаете, если бы цепочка связанного оформления полей запускалась полностью декларативно, тогда нет вопросов, и в вашем примере, это почти так и происходит через вентиль ОбработчикПриИзменении (). Но, повторю, мне очень редко встречаются случаи, когда изменяемый реквизит только то и делает, что влияет на оформление формы. Более частыми, идут задачи такого плана: установили галку -> ушли на сервер заполнять таблицу -> сделали там её (на сервере) видимой -> вернулись на клиент. Другой пример: изменили реквизит Договор -> получили из него валюту -> увидели что она не локальная -> сделали доступной состав реквизитов с курсом (не говорим про ФО). Оба случая, во-первых, желают изменить (в частности видимость) оформление на сервере, чтобы с клиента опять сервер уже платформа не вызвала (для видимости это произойдет почти наверяка), во-вторых - будут требовать от программиста как минимум одну строку кода для запуска обновления связанных полей, что в данном случае - фактически делает из декларативного подхода, просто копилку настроек оформления полей. И вот в этой связи, я предлагаю чуть другой подход - собрать неподдерживаемое условное оформление и применять его по необходимости. Решение не претендует на элегантность и новизну, но с практической точки зрения очень удобно (вопросы сравнения конфигураций с проблемой УО вынесем за скобки, потому тут тоже есть о чем подискутировать).
Подход можно посмотреть в конфигурации Тестер (https://github.com/grumagargler/tester), там два модуля Appearance и AppearanceSrv, применение см. в форме справочника Scenarios, написано по своим стандартам, на английском, поэтому вероятно, будет интересен с чисто теоретической точки зрения.
yarohagolovatiy; +1 Ответить
23. kalyaka 392 20.06.18 23:26 Сейчас в теме
(15)
очень редко встречаются случаи, когда изменяемый реквизит только то и делает, что влияет на оформление формы. Более частыми, идут задачи такого плана: установили галку -> ушли на сервер заполнять таблицу -> сделали там её (на сервере) видимой -> вернулись на клиент

Здесь я предлагаю четко различать часть связанную с оформлением формы и часть модели, когда происходит изменение данных. Эти части связаны в одну сторону: состояние формы отражает данные модели. Модель первична.

Вначале обсчитывается модель (заполняются таблицы, рассчитываются курсы и т.д.). Затем рассчитываются параметры состояния формы, некоторые из которых (базовые) опираются непосредственно на данные. От базовых рассчитываются зависимые. Получаем список измененных параметров состояния, от которых в свою очередь зависят настройки элементов формы.

Обсчёт модели происходит по зависимостям реквизитов. Более подробно механизм я описал в своей статье про MVC.

Так вот, если эти две модели соединить (MVC и состояние формы), то в модуле формы ничего программировать вообще не нужно будет - весь код будет располагаться для модели в модуле Менеджера (например), а для состояния в функциях состояния.

Оба случая, во-первых, желают изменить (в частности видимость) оформление на сервере
По любому работа с данными модели будет на сервере и заморачиваться с работой без контекста формы предлагаю только в исключительных случаях оптимизации. В большинстве случаев считаю методов оптимизации в платформе достаточно для приемлемой производительности интерфейса. Тогда обсчёт состояния формы можно и на сервере делать и код будет проще.

во-вторых - будут требовать от программиста как минимум одну строку кода для запуска обновления связанных полей
Не потребует, если использовать две модели (MVC+состояние формы).

собрать неподдерживаемое условное оформление и применять его по необходимости
Посмотрел, на английском без единого комментария выглядит как в лесу зимой: все кругом белым бело и голые деревья -процедуры :) Да, можно подумать о таком подходе, правда, здесь контекстный вызов сервера без альтернатив. И нужно придумать как обсчитывать условия по изменениям. И возможно описаний условий будет больше, чем в моем варианте. Одно дело задать все условия по разным свойствам оформления, другое - обыграть все это в коде функции состояния.
26. grumagargler 425 21.06.18 00:41 Сейчас в теме
(23)
Обсчёт модели происходит по зависимостям реквизитов. Более подробно механизм я описал в своей статье про MVC.

Так вот, если эти две модели соединить (MVC и состояние формы), то в модуле формы ничего программировать вообще не нужно будет - весь код будет располагаться для модели в модуле Менеджера (например), а для состояния в функциях состояния.

У меня был неудачный опыт описания логики работы формы декларативно. Я думаю, что единственное, на что годен декларативный подход - оформление. То, что в модуле ничего программировать не нужно, не нахожу преимуществом. Почему? Потому что непонятно, что, когда и где происходит, это сложно отлаживать (нужно помнить где ставить точки останова и делать их условными), добавим сюда отсутствие рефакторинга, который будет невыполним в строковых полях зависимости, невозможность анализа конфигурации (поиск неиспользованных обработчиков), сложности обработки равносвязных полей (например, ввод документа из журнала, где фильтром был склад и организацию нужно заполнить по его владельцу).
Не согласен с мнением "...заморачиваться с работой без контекста формы..."). Вы решаете проблему зависимостей, принося в жертву совсем немаловажные вещи. А такая ли уж большая эта проблема зависимостей? Я считаю, что небольшая. Даже обыденная вещь, как организация правильного клиент-серверного взаимодействия - это не вопрос оптимизации, это вопрос правильной архитектуры вашего кода в рамках проектных решений платформы (вопросы безопасности, отзывчивости интерфейса, а порой и обхода проблем с вызовом сервера самой платформы).

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

Посмотрел, на английском без единого комментария выглядит как в лесу зимой

Понимаю вас, но так в команде все пишут, это одно из требований.
29. kalyaka 392 22.06.18 00:13 Сейчас в теме
(26)
Потому что непонятно, что, когда и где происходит, это сложно отлаживать ...отсутствие рефакторинга, который будет невыполним в строковых полях зависимости

Тут я приведу аналогию с конвертаций данных. Если Вы владеете этой технологией, то представляете как можно отлаживать правила. Здесь я вижу аналогичный подход. Однако здесь, в отличии от Конвертации, используется несколько принципиально иной подход к обработчикам. Все обработчики вызываются как процедуры или функции, поэтому проблем с отладкой быть не должно, ведь весь код реально присутствует в модуле (впрочем сейчас принято весь код выкладывать в модуль), а не в текстовом аргументе процедуры Выполнить.

невозможность анализа конфигурации

Здесь соглашусь. Опять же сошлюсь на опыт с конвертацией данных. Для анализа нужно использовать отдельное решение типа конфигурации Конвертация.

большая эта проблема зависимостей?
Проблему я в свое время подробно исследовал в своих статьях (Шаблон MVC, Программирование интерфейсов)

было бы очень здорово, если бы вы накидали рабочий пример в типовой конфигурации

Такой пример я планирую выложить. Идея с типовой интересная. Действительно, зачем придумывать пример, если можно взять типовое решение и переложить его в новой подсистеме работы интерфейса. Возможно это будет очень затратно, но очень эффектно :)
16. rpgshnik 822 20.06.18 01:45 Сейчас в теме
Листинги не кликабельны, на мониторах 15" ни чего не видно.
У инфостарта при создание публикации есть "вставить сниппет" лучше бы его использовали.
18. kalyaka 392 20.06.18 09:26 Сейчас в теме
(16) в статье я сознательно отказался от сниппетов в пользу картинок для повышения иллюстративности кода в окружении.
С картинками однако есть проблема - они по разному отображаются при разном разрешении. На том же ipad или mac картинки выглядят четко. Попробуйте увеличить масштаб в браузере (у меня под windows при масштабе 175% исчезают боковые поля инфостарта и картинки показываются в разрешении близком к исходному) или же используйте просмотр картинок в исходном разрешении (нужно нажать (+) на картинке в заголовке статьи и там можно листать все иллюстрации)
С другой стороны весь приведенный код доступен в обработках и конфигурации, приложеных к статье.
yarohagolovatiy; +1 1 Ответить
17. evgen7938 20.06.18 04:40 Сейчас в теме
Конфигурацию не качал, но по тому, как преподносится материал, видно сразу, что решение очень хорошо спроектировано и учтены очень многие детали.
Лично я хочу выразить признание и уважение.
Вы проделали очень большую работу и уделили много внимания мелочам.
pbabincev; raider-rec@ya.ru; Evil Beaver; +3 Ответить
19. kalyaka 392 20.06.18 09:27 Сейчас в теме
20. Evil Beaver 5247 20.06.18 18:06 Сейчас в теме
Плюсую не читая. Сложные формы ВСЕГДА делаются на конечных автоматах. Радостно, что это приезжает в мир 1С.
harmit; tsukanov; +2 Ответить
30. WalterMort 279 14.08.18 10:31 Сейчас в теме
Для меня загадка, почему задача управления состоянием формы так будоражит умы 1С-ников. Не встречал решений в которых формы поголовно ведут себя вопреки заложенной логике. Не встречал программистов, настолько плохих, чтобы у них были трудности с управлением видимостью/доступностью. А вот что часто встречал - уродливые архитектуру и интерфейсы с кучей кнопок, полей появляющихся и исчезающих по ходу работы с формой, вечные вопросы пользователю и ещё портянки кода на обслуживание всего этого. Вот сделать форму понятной и лаконичной (а вместе с ней и код формы понятным и лаконичным) - автомат не поможет.
31. kalyaka 392 14.08.18 14:28 Сейчас в теме
(30)
Не встречал решений в которых формы поголовно ведут себя вопреки заложенной логике... А вот что часто встречал - уродливые архитектуру и интерфейсы с кучей кнопок, полей появляющихся и исчезающих по ходу работы с формой
Если я правильно Вас понял, хоть архитектура и уродлива, но работает верно: нужные кнопки появляются где надо и когда надо? Т.е. Вопрос только в том, что слишком запутанные алгоритмы обслуживают эти формы, их сложно сопровождать, но можно.
В принципе это наверно нормально, что сложные формы порождают сложные алгоритмы и архитектуру?
Так вот, идея автомата заключается в том, что вместо программирования поведения формы акцент делается на программирование состояний формы. При этом переход из одного состояния в следующее берет на себя подсистема, а программирование заключается в выделении таких состояний и описании их.
Что решает подсистема при этом: подсистема рассчитывает оптимальный переход и гарантирует соответствие конечного состояния заданному. Алгоритмически система берет на себя задачу: рассчитать измененные параметры состояния, найти зависимые параметры и рассчитать их, найти элементы формы или объединения элементов, состояния которых изменились, пересчитать их состояния и отобразить их на форме.
Почему это должно быть проще и надежнее? Потому что есть 100500 способов перехода из одного состояния в другое и есть только одно описание этого состояния. Подсистема берет на себя 1-ое, а второе должно быть согласно требованиям.
32. WalterMort 279 14.08.18 16:44 Сейчас в теме
(31) Я скорее о том, что сложные формы в принципе зло и их быть не должно. Надо в первую очередь думать как сделать сложную форму проще, а не превращать код сложной формы в нечитаемый манускрипт.

А про кучу состояний проблема надуманная, никто не будет описывать кубик Рубика его возможными состояниями. А вот принцип "разделяй и властвуй" - пожалуйста. Вот процедуры управления элементами одной закладки, вот другой. Всё прозрачно и понятно.
Универсальность решения имеет границу, пройдя которую она начинает вредить.
33. kalyaka 392 14.08.18 21:03 Сейчас в теме
(32)
Надо в первую очередь думать как сделать сложную форму проще

Хочу уточнить, Вы имеете в виду проще в плане реализации, но не в поведении?

А про кучу состояний проблема надуманна

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

А вот принцип "разделяй и властвуй" - пожалуйста

Согласен, пожалуйста :) В предложенной системе этот принцип заложен в основу. По другому Вы не сможете описать состояние формы: для описания Вам потребуется разделить форму на элементы и состояние каждого элемента необходимо описать. Есть возможность объединять элементы в логические группы и тогда достаточно описать состояния группы элементов.

Универсальность решения имеет границу

Концепция конечного автомата это не просто унивесальность, это другая парадигама мышления. Фактически это функциональный подход в программировании.
34. WalterMort 279 15.08.18 12:39 Сейчас в теме
(33) проще в поведении, конечно. Минимум элементов. А видимость менять вообще зло. В лучшем случае вид формы должен изменятся с одним реквизитом, видом операции, например. Остальные "спецэффекты" типа "тут включил - здесь появилось" это отстой. А когда форма имеет простое поведение, и городить ничего не надо.
35. kalyaka 392 15.08.18 16:02 Сейчас в теме
(34) Я тоже против перегруженных форм с большим количеством возможностей.

Однако именно управление видимостью позволяет делать формы более простыми для пользователя. Особенно в управляемых формах, когда скрытые элементы не занимают пространство.

А по поводу
Остальные "спецэффекты" типа "тут включил - здесь появилось" это отстой
могу привести пример проектирования интерфейсов для мобильных устройств. Например для apple используется технология сценариев взаимодействия на основе разработки последовательности экранов (даже не изменяемых форм, а отдельных экранов). И это не ведет к упрощению поведения, а наоборот к более адекватному взаимодействию с пользователем. Это я к тому, что индустрия стремиться к лучшему взаимодействию, а не к простым формам с низким уровнем взаимодействия (см. Примеры низкого взаимодействия из книги «Психбольница в руках пациентов» Алана Купера).

И возвращаясь к перегруженным и простым формам - на мой взгляд это две крайности. Нужно стремиться к формам с лучшим взаимодействием или с низким уровнем когнитивного сопротивления (Алан Купер), разве нет?
Оставьте свое сообщение