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

Я думал о том, как упростить создание общих бизнес-приложений (форм, форм и т. д.) лучше, быстрее, гибче и дешевле.

Проверенный метод

То, что часто делалось и реализовывалось различными способами, выглядит примерно так:

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

Как может выглядеть такой декларативный язык?

view:
  elements:
    - type: title
      label: Purchase order
    - type: textfield
      id: product
      label: Article
    - type: textfield
      id: amount
      label: Amount
    - type: button
      id: submit
      label: Place order
      action: /api/businessclient/order/new

Как это будет работать, так это то, что клиент интерпретирует этот список элементов и в основном составляет это:

Это будет работать точно так же, как простые HTML-страницы с формами. Когда вы нажимаете кнопку, контент отправляется на сервер, который может ответить новой страницей. Точно так же, как мы делали в первые дни веб-страниц, прежде чем веб-приложения стали вещью.

Варианты этого были реализованы снова и снова.

Ограничения

Хотя это отлично работает для простых случаев, у него есть некоторые недостатки:

  • Необходимо вызывать сервер для каждого действия, чтобы получить реакцию.
  • Любая логика, которая должна оцениваться на клиенте, должна быть либо жестко запрограммирована на клиенте (НЕТ), либо вам нужно придумать новые декларативные элементы (см. ниже).
view:
  elements:
    ...
  actions:
    - type: flashscreen
      for: 1000
    - type: beep
      times: 2
  • Если вы начинаете идти по маршруту декларативных действий, вам нужно реализовать их в каждой клиентской реализации, которая у вас есть.
  • Если вы хотите более динамичного поведения, вы, вероятно, закончите с действиями, которые принимают множество параметров и/или пытаются указать определенные отношения между элементами декларативным способом.

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

Идея

Некоторое время назад я понял, что сегодня почти все платформы имеют движки JavaScript:

Снова используем аналогию с HTML: в какой-то момент статические HTML-страницы с формами перестали быть достаточно хорошими и в веб-мире, и что мы там делали? Мы обратились к JavaScript, чтобы ввести динамическое поведение.

Поэтому я предлагаю не только отправлять декларативные описания представлений, но и включать код JavaScript, например:

view:
  elements:
    ...
    - type: textfield
      id: product
    ...
script: >
  function onProductExit() {
    if (!model.getValue('product')) {
      util.log('product field must be filled');
      ui.setFocus('product');
    }
  }

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

“on” + capitalize(fieldName) + “Exit”

Объекты модели, пользовательского интерфейса и утилиты также будут объектами, предоставляемыми клиентским приложением. Конечно, этот API, на который может полагаться код JS, должен быть определен заранее и доступен во всех клиентских приложениях.

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

Почему это круто:

  • Напиши один раз, беги куда угодно ;)
  • Тестирование: вы можете запускать скриптовые части клиентского кода с автоматическими тестами на сервере.

Вы можете найти некоторый демонстрационный код здесь, который показывает, что это работает с небольшим сервером и (действительно уродливым) клиентом Java8 Swing. Он даже включает тесты, которые начнут давать сбой, когда вы измените/удалите скриптовую часть ответа.

Поиск проблемы

Как упоминалось в начале, я уже подкинул эту идею нескольким людям и показал демо на сессии SoCraTes Day Linz 2016.

Ответы были по большей части… без энтузиазма. Вот отзывы и мои собственные мысли, которые я собрал по этому поводу:

Альтернативы:

  • ReactNative/NativeScript: они уже позволяют вам создавать клиентский код на JavaScript и запускать его в собственном приложении оболочки. Вы даже можете обменять практически все приложение, предоставив новые скрипты/ресурсы с сервера.
  • HTML/гибридные приложения: большинство современных мобильных экосистем также имеют довольно мощные браузерные движки, поэтому, если вы можете создать весь свой код в HTML+JS, у вас будет чрезвычайно гибкое решение. Даже если вам нужен доступ к API телефонов, есть другие технологии, которые позволяют это сделать (Apache Cordova, …)

Аргументы за его использование в любом случае:

  • Иногда гибридные приложения просто неприемлемы/желательны. И, возможно, вы/клиент скептически относитесь к таким технологиям, как ReactNative и т. д. Аргумент может быть таким: предоставить объект с 5-10 обратными вызовами для движка JavaScript легко и будет легко через 5 лет, поддержка приложения ReactNative может больше не быть легко к тому времени.
  • Вы можете рассматривать этот код как часть бизнес-логики (например, определенное поле должно соответствовать очень специфическому критерию), поэтому разумно держать его рядом с вашей бизнес-логикой и тестировать его вместе с остальными частями. По крайней мере, я бы предпочел, чтобы части этого внезапно оказались в каком-то совершенно отдельном клиентском проекте.

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

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

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

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