Как правильно создать графический интерфейс пользователя

#user-interface #architecture #ipc

#пользовательский интерфейс #архитектура #ipc

Вопрос:

Я работаю над серией различных программных продуктов. Они довольно старые, поэтому мы находимся в процессе их рефакторинга / улучшения. У моего коллеги возникла идея абстрагировать графический интерфейс и запустить его в собственном процессе и взаимодействовать с логической частью программы через сокеты. Это позволит нам использовать одни и те же компоненты GUI во всех различных приложениях (сохраняя один и тот же LAF). Итак, мой вопрос таков: является ли это допустимой практикой для создания GUI? Было бы лучше, если бы я сохранил привязку GUI к остальной части программы? каковы плюсы и минусы различных методов и существуют ли какие-либо другие методы реализации GUI?

Спасибо

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

1. Это совершенно верное решение. Для многих хорошо разработанных веб-приложений именно это и происходит. Клиент — это своего рода веб-браузер, а бизнес-логика выполняется на централизованном сервере.

Ответ №1:

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

Это немного необычно для настольного приложения, но вполне приемлемо. Прелесть этого решения в том, что оно позволяет вам писать несколько расширенных клиентов для разных платформ (например, мобильное приложение, приложение для Windows, браузерное приложение и т.д.)

Все, что вам нужно сделать, это определить API, который потребуется GUI для взаимодействия с серверной частью. Например, потребуется способ получения объектов и сохранения объектов, а также получения уведомлений от серверной части о том, что пользовательский интерфейс нуждается в обновлении.

Ответ №2:

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

Плюсы:

  1. Пользовательский интерфейс физически не привязан к логике, поэтому логические уровни могут быть удаленными (или даже автономным сервером BL для нескольких клиентов). Давайте назовем это «независимостью от местоположения бизнес-логики».
  2. Возможность создания различных версий GUI (и не только графических — можно было бы предоставить BL как сервис, например, как канал или конечную точку отчетности), «Независимость от платформы GUI», а также подход SOA.
  3. Возможность добавления прокси-сервера между BL и GUI — в целях безопасности и кэширования. Или балансировщик нагрузки перед фермой приложений. Или адаптер для поддержки «старых» клиентов после значительных изменений BL. («Отказоустойчивость»?)
  4. Развертывание могло бы быть в некоторой степени проще (исправление ошибок в пользовательском интерфейсе не повлияло бы на уровень BL — просто следствие независимости двоичного модуля)
  5. Возможность добавления «автономного режима» в графический интерфейс.

Минусы:

  1. Вы добавляете еще одну ссылку подключения, которая может стать еще одной точкой сбоя, и для ее тестирования следует потратить некоторые усилия.
  2. Увеличение трафика данных между GUI и BL и, вероятно, увеличение объема работы по сериализации.
  3. Необходимо отслеживать изменения протокола связи и поддерживать надлежащие версии протокола.
  4. (Отрицательная сторона прокси-способности) Возможность атаки «человек посередине» между GUI и BL.

Ответ №3:

Зависит от типа приложения.

Настольные приложения

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

Веб-приложения

ДА. Многие веб-приложения имеют отдельный уровень обслуживания и используют SOAP для связи между графическим интерфейсом и уровнем обслуживания.

Сокеты

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

Обновление в ответ на комментарий

Разделяй и властвуй. Разбейте пользовательский интерфейс на как можно более мелкие компоненты, чтобы сделать их повторно используемыми. Поместите эти компоненты в отдельный проект / dll. Примером компонента может быть пользовательская таблица, которая представляет список всех пользователей (с учетом зависимости от интерфейса IUserService ).

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

Вместо этого повторно используйте вышеупомянутые компоненты для создания конкретного пользовательского интерфейса для каждого приложения.

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

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

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

3. @BryanOakley: я обновил формулировку. Для настольных приложений это не так. Просто создайте библиотеку классов «сервера» и включите ее в клиент. Следование шаблону отдельного интерфейса упрощает его разбиение при необходимости. Это может иметь смысл, если сервер действительно является службой Windows, которой необходимо собирать / обрабатывать информацию, даже если приложение не запущено.