Переход от разработки локальных приложений c "виндоузным" интерфейсом к разработке WEB-приложений требует достаточно радикальной смены парадигмы от разработчика. И в этой статье я попытался выделить и описать отличия в подходах к разработке этих двух классов систем и вообще - мое впечатление от WEB-а, как "высшей и последней стадии" развития пользовательских интерфейсов.
Возможно, эта статья несколько запоздала - основные идеи, изложенные в ней, были осмыслены и сформулированы мной года четыре назад, когда я вместо разработки корпоративных GUI-приложений занялся публичными web-сервисами.
Но сейчас наметилась тенденция к так называемой "глобализации" информационных систем, т.е. переделки "локальных" систем в интранеты. Упомянутой глобализаций сейчас занимаются многие западные корпорации. Соответственно, растет число разработчиков веб-систем. Так что эта тема мне снова показалась актуальной.
Ты помнишь, как все начиналось, или хорошо забытое старое
На моей памяти WWW - это пятое поколение интерактивных интерфейсов.
1. Первыми были терминалы для ЕС-овских машин. Но суть их была не в том, что они были большие, железные и алфавитно-цифровые, а в том, что они обменивались с такой же большой и железной ЕС-кой большими (правда, не железными) блоками информации - на терминал присылался целиком образ экрана (или даже чуть больше), а обратно, по нажатию специальной кнопочки "Передача" назад отправлялся тот же образ, только отредактированный.
Потому как отвлекать жудко производительный (целых 50 тысяч операций в секунду) суперкомпьютер на обработку каких отдельно взятых кнопочек тогда и в голову никому не приходило.
А в промежутке между приемом и посылкой буфера эти терминалы работали сами по себе - как будто никакой ЕС-ки нет. Иногда при нажатии кнопки "Передача" оказывалось, что ее (ЕС-ки) и вправду нет - точеее, физически есть, а логически нет - повисла.
А поскольку использовались терминалы не только (и не столько) для ввода текстов, сколько для структурировнной информации (форм), то эти терминалы умели поддерживать формы аппаратно - во входном буфере им определенным образом передавалось описание формы на "птичьем языке", а при передаче с терминала в ЕС-ку передавался не весь экран, а только содержимое полей формы.
2. Затем появились дисплеи с последовательным вводом-выводом, для которых уменьшившиеся в размере, но усилившиеся нутром (и улучшившиеся архитектурой) миникомпьютеры (СМ-ки и иже с ними) таки обрабатывали нажатия отдельных кнопочек и выводили на экран отдельные буквочки в указанных позициях.
Тут уже свои интерфейсы ввода начали программировать все кому не лень (я в свое время тоже отдал этому дань).
3. Следующим поколением явились персональные компьютеры с по-прежнему алфавитно-цифровыми (в основном режиме работы), но уже цветными мониторами, и с самым "прямым" способом работы с экраном - выводом в видеопамять. Обработка входящих кнопочек о прежнему лежала на центральном процессоре, но к кнопочкам добавился еще манипулятор типа "мышь", перемещения и нажатия которого тоже можно было обрабатывать.
В связи с усложнением задачи, начали широко использоваться всякие полустандартные библиотеки для создания интерфейсов (типа Borland TurboVision), хотя любителей пописать в видеопамять и пообрабатывать прерывания от клавиатуры и мыши оставалось еще достаточно.
Поэтому интерфейсы ДОС-овских систем были еще достаточно разнообразны по набору использовавшихся метафор.
4.Предоследним и ныне здравствующим поколением являются оконно-формовые интерфейсы типа Windows. Мощность процессоров окончательно победила здравый смысл, все стало рисоваться исключительно в графике, причем масштабируемыми TrueType-шрифтами. Мазохисты, любящие писать в видеопамять или даже использовать базовые примитивы ввода/вывода, доступные в Windows, остались только среди разработчиков игр, причем даже не самих игр, а движков к ним.
Все остальные пересели на стандартные библиотеки, покрывающие железо таким толстым слоем, что про него оказалось проще забыть. И с этим в в мире локальных (GUI) приложений окончательно воцарилась нынешняя интерфейсная метафора, основанная на понятиях
- окна - самостоятельной прямоугольной области экрана, размером которой управляет пользователь
- управляющего элемента (контрола) - квазисамостоятельного прямоугольного элемента в окне с фиксированным размером и координатами.
Причем не потому, что она является единственно возможной и самой удобной, а потому, что ее (как самую простую) поддержали производители базового ПО.
Некоторые простейшие способы описания динамики (перемещения и изменения размеров) управляющих элементов в при изменении размеров окна появились в наиболее продвинутых системах разработки, но описать с их помощью разумное поведение окон со сложными структурами все равно не получалось.
И казалось, что так будет всегда, пока не появился WEB. Точнее, пока протокол HTTP не начали использовать для построения интерфейса к удаленным системам, а не просто как способ посмотреть домашнюю страничку Васи Пупкина.
5. Время замкнулось, Великий змей ухватил себя за хвост и выяснилось, что по логике работы "сверхтонкий браузер-ориентированный клиент" ничем не отличается от большого железного терминала 20-летней давности.
Точно также сервер должен сформировать в текстовом (HTML) виде блок передаваемой пользователю информации, автономное устройство (правда, сейчас это компьютер, а не терминал) должно обеспечить возможность ввода/корректировки информации, и отправить введенную информацию на сервер по нажатию очень специальной кнопки.
Конечно, нынешние персональные компьютеры по мощности на много порядков превосходят старые терминалы (да и мэйнфреймы), и HTML гораздо выразительнее, чем язык кодовых последовательностей терминала 7920, но принцип остался тот же.
Отличия и проблемы
Разный принцип работы удаленного (браузерного) и локального (GUI) интерфейсов (да и вообще - приложений) обуславливают совершенно разный подход к их проектированию и разный "look and feel" для пользователя.
Итак, в чем же фундаментальные отличия HTML-интерфейсов от интерфейсов локальных систем?
1. У браузерного приложения сервер находится далеко, и по мелочам его дергать нельзя.
Т.е. типичные для локального приложения приемы, когда при переходе курсора в какое-то поле идет запрос к базе для выборки данных, совершенно неприменимы в случае браузерных приложений. Т.е. интерфейс должен быть по возможности, автономен, и о загрузке необходимых данных на клиента нужно заботиться заранее. Причем заботиться нужно также о том, чтобы их количество было по возможности минимально...
2. Гораздо более сложное и ограниченное по возможностям программирование "тонкой реакции" на нажатия кнопок.
Причем кое-где возможности веб-форм даже слабее, чем у старых добрых мэйнфремовских терминалов (типа, скажем 7920) - нет возможности, например, по-простому задавать порядок обхода полей табуляцией, ограничивать набор символов, вводимых в поле и обеспечивать автотабуляцию при переходе в другое поле.
Моему знакомому, который занимается пресловутой "глобализацией" систем для мэйнфремов в одной из наших оффшорно-программистских контор, для решения этих задач пришлось "с нуля" написать систему обработки клавиатурного ввода на JavaScripte, перехватывающую и интерпретирующую нажатия отдельных кнопочек (мы таким развлекались на СМ-ках в 1983-84 году:)
3. В отличии от локальных систем, количество пользователей которых всегда ограничено, и эти пользователи могут быть "построены" в силу своей территориальной локализации, браузерными интерфейсами обычно снабжаются системы удаленного обслуживания, рассчитанные на потенциальное использование неограниченным кругом, вообще говоря, недисциплинированных лиц.
Это задает совершенно иные требования к принципам проектирования систем (правда, больше не к интерфейсной, а к серверной их части), связанные с явным выделением и управлением пользовательскими контекстами, и разрешением многопользовательских коллизий в БД.
Потому что сидящему неизвестно где пользователю ты не можешь запретить открыть форму ввода и уйти обедать.
3. В отличии от локальных приложений, браузерные интерфейсы всегда и принципиально многооконны (многосессионны), причем идеология этой многооконности совершенно другая, нежели у типичных GUI-приложений - нет понятия модальных окон, окна реально независимы (нет возможности синхронизировать их содержимое), открываются и закрываются без какого-либо контроля со стороны сервера, и др. Много проблем добавляет разработчикам и кнопка "Назад", которую часто хочется, но не всегда можно заблокировать.
Поэтому у web-приложения, как правило, нет четко выраженного понятия "состояния исполнения" программы и можно ждать от пользователя любой пакости.
Эту многосессионность можно ограничивать средствами сервера, искусственно обеспечивая единый поток управления, но это приводит к крайне не интуитивно ведущим себя приложениям.
Работа с базами данных.
Отдельно нужно сказать о различии интерфейсных метафор при работе с базами данных в случае GUI- и WEB-интерфейсов.
Как я уже писал когда-то в "Блексе и нищите клиент-серверных технологий", основная задача инструментария для разработки локальных (GUI) СУБД-шных приложений - сделать вид, что никакого клиент-сервера у нас нет, и пользователь успешно работает со своей настольной СУБД. И на это ориентированы соответствующие интерфейсные метафоры.
В этом смысле WEB -система требует существенно более честной реализации идеологии "клиент-сервер", поскольку требует минимизировать количество обращений к серверу. И метафоры "простыни" (grid-a) которую мы неограниченно листаем вверх-вниз, тут нет и быть не может.
Поэтому использование форм запроса для явной спецификации того, что мы хотим получить, и неявные запросы путем перехда по связями получили существенно более широкое распространение, чем в GUI-приложениях. А обширная выдача в ВЕБ-е всегда четко нарезана на страницы небольшого объема, с явно выраженной и достаточно "тяжелой" операцией листания. Зато хорошей практикой стала выдача информации о суммарном количестве записей в получившейся выборке...
И в общем, выяснилось, что от отсутствия пресловутой "простыни" и понятия "текущая позиция в таблице" никто особо не страдает. Так что я даже начал задумываться - а так ли она необходима даже в настольных приложениях?
Еще, как я писал выше, для web-систем неприемлим "пессемистический" подход, основанный на блокировках записей, взятых на редактирование. Могут использоваться только "оптимистические" стратегии, основанные на проверке многопользователских изменений при попытке записи данных.
Причем этот момент требует особого внимания, так как существование кнопки "Назад", возможность остановки запроса на запись и попытки повторного его исполнения тем же пользователем гораздо более вероятны, чем собственно, многопользовательские коллизии.
Управление контекстами
Разработчики локальных приложений редко сталкиваются с понятием контекстов в явном виде (оно вылезает только при использовании низкоуровневых серверов приложений типа Taxedo).
В классическом GUI-приложении, когда каждый пользователь обслуживается отдельной копией задачи, контекст "замурован" в набор данных и состояние исполнения (cтек) задачи.
В случае веб-приложения все пользователи обслуживаются, как правило, одной задачей (web-сервером и сервером приложений). И этот самый сервер, получив "пинок" от браузера, должен понять - что делать, и какой HTML сгенерировать и отдать этому браузеру.
При этом он должен основываться как на информации, полученной им в составе запроса (URL,логин/пароль, параметры, куки), так и на некоторой предопределенной информации. Эта информация разделена, как правило, на общую для всех пользователей БД, и область данных, созданную для данного конкретного пользователя, и хранящую информацию, накопленную в ходе предистории его работы.
Эту область данных мы будем называть контекстом, а период его существования - от момента входа пользователя в систему до уничтожения контекста - сессией. Контекст идентифицируется либо по имени пользователя, пришедшему в составе запроса, либо по специальному идентификатору сессии, который ``гоняется'' между браузером и сервером либо в параметрах URL (вы наверняка видели при работе с разными веб-сайтами в URL что-то типа session_id=ХХХХ), либо в куке.
Существование контекста ставит множество тонких вопросов - например, когда убивать сессию. Обычно это делается спустя некоторое время (тайм-аут) после того, как пользователь перестал проявлять активность.
Еще одну проблему создает наличие многооконности и кнопки "назад". Потому как состояние окна браузера, в котором пользователь активирует свой запрос, может оказаться совсем не таким, как ожидается, исходя из состояния данных в его контексте. Поэтому иногда последовательность жестко ограничивают, передавая не только идентификатор сессии, но и временной штамп, обновляемый при каждом запросе, и при получении "устаревшего" штампа отказывая в обслуживании запроса, и/или принудительно возвращая пользователя в контекст, который система считает "текущим".
Но это приводит к совершенно неочевидному поведению системы с точки зрения пользователя, привыкшего к возможности открытия многих окно и свободному использованию кнопки "Назад", поэтому лучше все-таки строить систему таким образом, чтобы ее поведение в минимальной степени определялось контекстом, а в максимальной - информацией, полученной в ходе запроса, и текущим состоянием БД.
Существующие сервера веб-приложений, поддерживающие наиболее популярные технологии (PHP,ASP,JSP) поддерживают понятие сессий, полностью принимая на себя управление (создание, отслеживание, удаление) контекстами.
Но в явном виде понятие сессии нужно не всегда - часто необходимый контекст вполне можно держать в куках и/или базе данных. Скажем, в системе разработки Communiware сессии в явном виде вообще нет.
Но четкое понимания контекста необходимо и в этом случае. Поэтому проектирование веб-систем в этом смысле требует "выворачивания наизнанку" сознания разработчика, привыкшего к GUI, потому как оно должно начинаться с выделения множества элементарных операций, которые может совершать пользователь, и проектирования единого информационного блока (контекста), обеспечивающего возможность выполнения операций, и только потом - проектирования интерфейса для совершения этих операций.
Промежуточные варианты
Описанные выше фундаментальные различия породили много попыток решить их и с с помощью каких-то инструментальных средств программирования. Попытки эти шли по двум направлениям, решающим, вообще говоря, разные задачи.
1. Замена HTМL-интерфейсов специализированными агентами (ActiveX, Java-апплеты, в какой-то степени Flash и др.).
Этот подход заметно упрощает программирование кнопочек, но сталкивается с проблемой совместимости разных платформ (скажем, именно поэтому от него отказались в упоминавшемся мной проекте глобализации). Кроме того, при этом исчезает главное преимущество HTML-интефейсов - их стандартность и гибкость, о которых мы поговорим чуть дальше.
2. Разработка библиотек и серверов приложений, обеспечивающих "трансляцию" локальных интерфейсов через веб - как я их назвал в свое время, "веб - удлинители". Одной из таких систем был Байконур, с которым мне пришлось плотно поработать в конце 90-тых.
На первый взгляд, такая система решала все вопросы, как с техникой построения интерфейсов, так и с обеспечением контекстов (в базовом варианте на каждого пользователя там честно запускалась копия приложения), но ближе к делу это оказалось иллюзией, поскольку
- интерфейсы и логику приложений все равно приходилось проектировать, учитывая ограничения ВЕБ-а
- автоматически сформированные экраны получаются некрасивыми, и не использующими преимуществ HTML-интерфейсов.
- издержки на поддержку множества запущенных полноценных приложений оказывались слишком велики, и все равно пришлось переходить на систему с единым сервером приложений и явным хранением контекстов.
Поэтому мы изначально говорили, и дальше будем говорить о классических HTML-интерфейсах, которые, кроме описанных выше проблем, предоставляют некоторые существенные возможности и удобства, на мой взгляд, перевешивающие все недостатки.
Наша сила - обратная сторона нашей слабости
С моей точки зрения, основным преимуществом веб-интерфейсов является
- возможность органичного сочетания активных и пассивных элементов на экране,
- разумное поведение изображения при изменении размеров и формы окна
- и отсутствие каких-либо ограничений на количество активных элементов.
В классических GUI-приложениях всегда есть разница между формой, относительно простой по своей структуре, но позволяющей активно работать с представленными в ней данными, и отчетом, устроенным сколь угодно сложно, но пассивным. В HTML-приложениях это различие нивелируется, так как управляющие конструкции также описываются текстом, и также легко генерируются, как и любой другой текст.
Т.е. в HTML нет разницы между формами и отчетами, и это, на мой взгляд, фундаментальное преимущество веб-интерфейсов перед GUI, перевешивающее все их недостатки.
Даже возможность перехода от упоминания объекта в любом контексте к описанию объекта, тривиальная для любого веб-приложения (ссылка), проблематична для широкомасштабной реализации в GUI. Не говоря уж о возможности встраивания форм редактирования объектов, которые генерируются в HTML так же легко, как и просто текст.
Далее - бедность изобразительных средств HTML обеспечивает высокий уровень стандартизации приложений (пользователь получает единообразный интерфейс), и существенно ограничивает возможность авторских изысков, которые чаще идут во вред, чем во благо.
В то же ограниченность средств, как правило, стимулирует творческое воображение, позволяя разработчику сосредоточиться на сути. Примером этого является поэзия, где искусственные ограничения на порядок и количество слогов и их созвучность не препятствуют созданию великих произведений, причем в классической, рифмованной форме их гораздо больше, чем в жанре белого стиха, где эти ограничения сняты.
(
написано 08.06.2004,
опубликовано 28.06.2004)
|