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

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

Перейти к публикации

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

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

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

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

Показать


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

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

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

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

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

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

Идея должна либо умереть, либо превратиться в практику. Это как с новым изобретением. Вначале собираются устройство образно на "соплях". Демонстрируют и убеждают вложиться. После, как говорят, идея должна преодолеть пустыню смерти.
5. unichkin 1275 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 583 20.06.18 20:48 Сейчас в теме
(5) про общие модули «ОбщийВызовСервера», «ОбщийКлиентСервер». Не знал, что они вообще кого то привлекут внимание. Дело в том, что эти модули я использую во многих разработках и не только я.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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