Реферат: Ордена ленина институт прикладной математики им. М. В. Келдыша Российской Академии Наук




ОРДЕНА ЛЕНИНА

ИНСТИТУТ ПРИКЛАДНОЙ МАТЕМАТИКИ

им. М.В.Келдыша

Российской Академии Наук


Е.Л.Китаев, Д.Л.Кузьмичев, М.И.Слепенков


Особенности реализации насыщенных пользовательских

интерфейсов Веб-приложений


Москва, 2006

Настоящая работа поддержана Российским фондом

фундаментальных исследований,

грант № 05-01-00456


Аннотация


В работе рассматриваются особенности реализации Веб-приложений с насыщенным интерфейсом (приложений Web 2.0), где активно применяются средства многооконной визуальной компоновки документов на стороне клиента. Отмечаются трудности при создании функциональных связей между DHTML-компонентами, расположенными в разных окнах клиентского приложения, вызванные асинхронным режимом клиент-серверного обмена в среде Интернет. Представлена идея адаптации схемы взаимодействия компонент из архитектуры MVC Smalltalk и описаны программные механизмы для простого и удобного внедрения этой схемы в задачах Веб-разработки. Демонстрируется применение предложенных решений в реальной системе онлайновой биржевой торговли.


Some aspects of rich user interface implementation in Web-applications

Abstract


The paper discusses some aspects of rich user interface implementation in next-generation Web-applications (Web 2.0 applications), which actively use multi-window and multi-document design for building representation on the client-side. We describe difficulties involved into maintaining behavioral relationships between DHTML-components located in different windows of client application, determined by asynchronous mode of client-server communications in the Internet. An idea to adapt the MVC Smalltalk-based architectural pattern for component interaction is evaluated and it is refined into the description of programming tools for simple and convenient implementation of this pattern in Web projects. In conclusion we demonstrate viability of the proposed solutions by considering an example of real online market exchange system.


Содержание


Введение 3

1. Режимы клиент-серверного взаимодействия и их особенности 5

2. Обоснование выбора схемы взаимодействия компонент 14

3. Предлагаемые решения для организации взаимодействия DHTML-компонент 17

4. Пример практического использования механизмов синхронизации 26

Заключение 31

Список литературы 31



Введение

Несмотря на многочисленные трудности, связанные с реализацией программных систем в среде всемирной паутины World Wide Web,создание решений на платформе Веб вот уже более десяти лет образует наиболее перспективное и динамично развивающееся направление современной индустрии разработки приложений. Целые классы приложений, которые ранее распространялись или могли бы распространяться в виде «настольного» (desktop) программного обеспечения, предназначенного для установки на компьютерах пользователей - такие, как системы интерактивного общения (конференции, чаты), онлайновой торговли и резервирования (электронные магазины, аукционы, биржевые площадки, заказ билетов и номеров в отелях), библиотечные каталоги, интерактивные географические атласы, игры, автоматизированные рабочие места (администраторов, контент-менеджеров, корпоративных пользователей) - перемещаются в среду Веб и, в конечном итоге, этот процесс «вебификации» (weblication) программного обеспечения проходит очень успешно.

В настоящее время отмечается рост ожиданий относительно перспектив дальнейшего развития отрасли Веб-приложений и, даже, предсказывается очередной бум вебификации в набирающей популярность концепции «Веб нового поколения» (Web 2.0) [1]. Одной из главных, отличительных черт приложений Web 2.0 становится поддержка полноценного, насыщенного (rich) пользовательского интерфейса, который должен наконец-то приблизиться к традиционным «настольным» интерфейсам по своим функциональным возможностям, интерактивности, удобству и эффективности использования.

Приложения подобные Gmail [6], Google Maps [7], Flickr [8] оставили в прошлом привычную для разработчиков модель «тонкого» клиента, и заставили в полной мере работать стек технологий DHTML (JavaScript [5]/DOM [3]/CSS [4]), заложенный в стандартной архитектуре современного Веб-клиента. Вместе с тем нельзя не заметить, что создание таких приложений является очень трудоемкой, сложной в техническом плане и, даже, рискованной задачей, из-за чего инвестировать в такие решения до недавних пор могли себе позволить только такие гиганты программной индустрии, как Google или Microsoft.

Однако, положение дел в этой области быстро меняется. Активное обсуждение и исследование проблем применения стандартных клиентских Веб-технологий при создании приложений с насыщенным интерфейсом позволяет выделить такие методы и способы их использования, овладение которыми не требует знания всех тонкостей DHTML-программирования, и которые – при условии адекватного инструментального обеспечения – можно сделать легко доступными для тиражирования. Такой подход, направленный на построение технологической надстройки над конструкциями DHTML, который сегодня принято обозначать термином AJAX (введенным в [2]), в настоящее время уже вышел из стадии «лабораторных исследований» и подкрепляется достаточно солидным списком AJAX-инструментов (см., например, [9] [10]), доступных для применения в реальных задачах Веб-разработки.

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

Тематика настоящей работы построена вокруг одной из «аксиом», существующей в Веб-программировании - обеспечение дружелюбности (usability) пользовательского интерфейса приложения, с учетом того, что все взаимодействия между клиентом и Веб-сервером должны производиться в асинхронном режиме. Это в одинаковой мере относится как к выполнению передачи данных, так и к перемещению необходимых для работы клиентской части приложения программного кода и элементов визуального интерфейса. К сожалению, эта «аксиома» часто нарушается в существующих AJAX-приложения, когда в процессе их работы подозрительно часто появляются окна с сообщением: «Подождите, идет загрузка нужных компонент/данных», а сам интерфейс как бы зависает. Такая техника фактически воспроизводит поведение «чужеродных» для Веб Java-апплетов, которые полностью блокировали страницы, в которые они встраивались, и в значительной мере поэтому, так и не прижились в Веб-интерфейсах.

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

^ 1.Режимы клиент-серверного взаимодействия и их особенности

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

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

Очень поучительным в этой связи и, одновременно вызвавшим большие нарекания со стороны пользователей, моментом стал период выхода в Интернет клиент-серверных решений, ранее ориентировавшихся на работу в условиях локальных сетей. Зачастую, вся адаптация этих систем к Интернет сводилась к реализации соответствующего прикладного протокола в стеке TCP/IP, но при этом оставался неизменным традиционно принятый в локальных сетях синхронный режим доступа к серверу (например, к файловому серверу или серверу баз данных). Этот период запомнился появлением большого количества клиентских приложений, «умирающих» после обращения по глобальной сети. Для исправления ситуации потребовались немалые усилия – пока в дизайне приложений не стали, как обязательные элементы, появляться кнопки «Stop» и индикаторы прогресса, а разработчики не научились азам использования асинхронных вызовов и многопоточности для предотвращения блокировки пользовательского интерфейса во время длительных операций клиент-серверного обмена .

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

Таким образом, при том разделении задач между программными составляющими броузера и Веб-приложения, которое принято в классической модели, броузер принимает на себя роль посредника между пользователем и приложением, размещенным в сети, и гарантирует определенное качество, управляемость работы приложения. При этом все проблемы, возникающие в связи с обеспечением асинхронного режима доступа к Интернет, относятся к сфере ответственности разработчиков программного обеспечения броузера. Например, именно им приходится «ломать голову» над тем, какую часть страницы из того, что уже получено с сервера, можно отобразить на экране, а какую – пока рано. Асинхронность также отражена и в самом дизайне Веб-броузера, где в частности предусмотрена кнопка Stop (чтобы пользователь мог в любой момент остановить загрузку очередной страницы), кнопки Back и Forward (чтобы можно было в любой момент перейти на предыдущую или следующую из просмотренных страниц) или, наконец, кнопка [X] в верхнем правом углу окна броузера (чтобы просто штатным образом закрыть приложение не дожидаясь пока завершится очередное соединение с сервером).

Приложения нового поколения Web 2.0, обладающие насыщенным пользовательским интерфейсом, основаны на совершенно иных принципах работы. Например, при реализации интерфейса типа single page interface (описанного в [17]) головная страница, загруженная в окно броузера, принимает на себя все функции полноценного клиентского приложения. Она может многократно в ходе своего жизненного цикла запрашивать с сервера нужные ей данные, порождать дочерние окна (вложенные, диалоговые, всплывающие и т.п.). При реализации таких приложений становится возможным выбирать режим доступа к серверу – синхронный или асинхронный. Таким образом разработчик подобных приложений принимает на себя ответственность за обеспечение новых требований к пользовательскому интерфейсу, которые раньше в классической схеме Веб-приложения являлись исключительной прерогативой броузера.

Для иллюстрации этих особенностей и возможностей воспользуемся следующим несложным примером. Предположим, что надо реализовать форму (qry_report_from) для задания параметров некоторого отчета, в котором должны быть представлены данные, выбираемые по интервалу календарных дат. Такая форма будет иметь два поля для ввода начальной (from_date) и конечной (to_date) даты, а также ряд дополнительных полей для задания параметров отчета (например, поле «Тип отчета», позволяющее выбрать краткую или полную форму отчета) и кнопку «Получить отчет». Кроме того, что дату можно непосредственно ввести в поле с клавиатуры, это можно сделать и через календарь. Для вызова календаря рядом с полями для задания дат есть кнопки from_date_button и to_date_button, представленные на следующем рисунке.





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

устанавливать связь с полем, в которое будет помещена выбранная в календаре дата;

позиционировать себя рядом с полем даты

при открытии выставляться на дату, указанную в поле дату либо на текущую дату, если поле пусто;

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



Конечно самый простой вариант реализации данного примера – это включить компоненту-календарь непосредственно в форму, сделав ее невидимой в момент загрузки страницы. Тогда достаточно определить обработчики событий (onclick) нажатия кнопок from_date_button и to_date_button как:











// аналогично
// event=”onclick”>


В данном случае объект calendar доступен нам на странице с параметрами отчета все время, и он инициализируется в обработчике события onload. Мы находим эту компоненту (idCalendarComponent) на странице и запоминаем ссылку на нее в переменной calendar. Соответственно, теперь нет никакой проблемы, чтобы открыть календарь в контексте нужного поля даты, непосредственно обратившись к его методу calendar.show

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

Если загружать календарь через отдельное обращение к серверу, то при реализации такого варианта возникает искушение ничего по большому счету не менять в программном коде, и использовать синхронный режим обмена между клиентом и сервером, который часто практикуется в ряде AJAX-приложений. Раньше это было не так-то просто сделать, потому что все API стандартного клиента исключали возможности синхронного обращения к серверу и, чтобы этого добиться, надо было пускаться на разные хитрости. Однако, сегодня стал доступен компонент XMLHttpRequest, который можно считать уже стандартным (см. [18], [19]) и в котором заложена возможность синхронного обращения (атрибут asynс, управляющий режимом обмена). В этом случае представленный выше программный код может быть переписан следующим образом:








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

Для того, чтобы избавить реализацию от подобных недостатков, компонента должна загружаться с сервера в асинхронном режиме. Вообще говоря, данный режим является основным, принятым в современных стандартных Веб-клиентах, способом обращения к серверу. Причем, программистам для работы в асинхронном режиме не требуется решать каких-то запредельно сложных задач, подобных обслуживанию сетевого взаимодействия на уровне сокетов TCP/IP. В равной мере, в тексте программ не надо выделять критические секции, поскольку модель исполнения программного кода, написанного на языке сценариев (JavaScript, VBScript), является однопотоковой.

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

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

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

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











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

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





Представленный пример наглядно иллюстрирует недостатки распространенного сегодня подхода к реализации, который предполагает анализ набора всех возможных комбинаций состояния компонент системы и создание отдельного варианта реализации для каждого из случаев, требующих самостоятельной обработки. Видно, что это приводит к дублированию программного кода, когда одно и то же действие (в примере – открытие календаря) вынужденно реализуется с использованием разных механизмов и в разных местах (на странице с параметрами отчета и в коде календаря, загружаемого в IFRAME). Если нужная компонента (в данном случае – календарь) загружена, то для передачи управления в нее достаточно простых прямых вызовов. С другой стороны, когда компонента не загружена или находится в процессе загрузки, то приходится направлять взаимодействие в обратную сторону. Для этого оказывается необходимым вводить для представления состояния переменные, в соответствии с которым компонента на фазе своей инициализации выполнит нужные действия (т.е. действия, которые при прямом обращении производились непосредственными вызовами). Подобная техника является гораздо более трудоемкой по сравнению с синхронной подкачкой, но это на данный момент представляется неизбежной платой за обеспечение требований к построению удобного, насыщенного пользовательского Веб-интерфейса, по сравнению с которыми проблемы реализации уходят на второй план.

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

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

^ 2.Обоснование выбора схемы взаимодействия компонент

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

Хотя особенности, отмечаемые при реализации насыщенных Веб-интерфейсов не типичны для современных средств поддержки разработки, в недавнем прошлом можно найти программные средства с аналогичными свойствами. Прежде всего имеется ввиду широко известная архитектура пользовательского интерфейса, названная Model-View-Controller (MVC) в той своей первоначальной инкарнации, когда она появилась в языке Smalltalk-80 [11] [12].

Система интерактивного пользовательского интерфейса, реализуемая на основе этой архитектуры, содержит три четко выделенных уровня, так называемая MVC-триада: модельный слой (model), инкапсулирующий представление данных и реализацию бизнес-логики приложения; слой презентации (view), определяющий правила формирования внешних форм, отображающих состояние приложения на экране; а также управляющий слой (controller), отвечающий за преобразование событий пользовательского интерфейса (нажатие кнопок клавиатуры, мыши и т.п.) в вызовы операций бизнес логики. Взаимодействие между этими слоями подчиняется жесткой системе ограничений, в соответствии с которой модельный слой не должен иметь прямых обращений к презентационному и управляющему слоям; слой презентации получает уведомления об изменении состояния приложения через механизм наблюдателя (observer); наконец, управляющий слой не может непосредственно модифицировать внешнюю форму и может воздействовать на состояние слоя презентации только опосредовано, через модификацию состояния модельного слоя.

Сегодня, в приложении к современным системам поддержки разработки пользовательского интерфейса, использование MVC-архитектуры в основном сводится к выделению тех технологических преимуществ, которые вытекают из четкого концептуального отделения данных и логики приложения от определения форм внешнего интерфейса. В частности, этот принцип разделения слоев, принятый в MVC, можно увидеть в основе многочисленных сервер-ориентированных систем для создания Веб-приложений (Struts, Spring Web MVC., Java Server Faces и др.).

Однако следует отметить, что применение MVC для построения пользовательского интерфейса в среде Smalltalk преследовало не только концептуальные, но и определенные операционные цели, связанные с необходимостью поддержки динамически конфигурируемой архитектуры (pluggable architecture), что в свою очередь позволило обеспечить возможность оперативного подключения и отключения компонент внешнего интерфейса в работающем приложении (без его остановки и перезапуска). Этот операционный подход MVC в Smalltalk оказывается очень близок к тем условиям, в которых функционируют насыщенные клиентские интерфейсы в среде Веб, и поэтому будет целесообразным более подробно остановиться на введенных в Smalltalk механизмах поддержки взаимодействия программных слоев MVC.

В общих словах, свойства динамически конфигурируемой архитектуры пользовательского интерфейса обеспечиваются за счет накладываемого в триаде MVC требования отсутствия прямых зависимостей модельного слоя по отношению к слоям управления и презентации. Это требование, в свою очередь, приводит к необходимости реализации потока синхронизации изменений между модельным и презентационным слоями, обращенном в обратном направлении по отношению к основному потоку управления (так называемая pull-синхронизация). Последнее предполагает, что разработчику должны быть доступны программные механизмы, необходимые для реализации pull-синхронизации – известные также как средства квази-непрерывного, статусного взаимодействия (если пользоваться терминологией из области статусно-событийного анализа, представленной в работах [13] [14]).

В роли базового программного средства для pull-взаимодействия между компонентами MVC в Smalltalk было предложено использовать механизм Наблюдателя (Observer-Observable, Publish-Subscribe), который однако, как показал опыт практического использования, оказался инструментом, доступным только для системных программистов высокого уровня квалификации (собственно, на этот уровень рассчитывалась тогда MVC). В частности, одной из наиболее неприятных проблем, характерных для подобных процедурных механизмов pull-синхронизации, является отсутствие встроенного механизма, позволяющего предотвратить зацикливание программы.

Отмеченные возможности архитектуры MVC, заложенные в Smalltalk, нашли свое развитие в еще одной известной реализации – Java Swing [15], где все стандартные элементы форм в пользовательском интерфейсе (кнопки, поля ввода, меню, таблицы и т.п.) построены по принципам MVC с использованием механизма Наблюдателя [16]. За счет этого в Swing обеспечивается уникальная возможность настройки внешнего вида стандартных компонент пользовательского интерфейса, который может в процессе работы приложения динамически подстраиваться под образ элементов из различных операционных систем (pluggable look-and-feel) путем простой замены объектов в слое, отвечающем за визуализацию элементов. С другой стороны показательно, что в Swing для компоновки прикладных форм – т.е. решения задач, относящихся к компетенции прикладного, а не системного программиста - схема MVC и механизм Наблюдателя не используются. Здесь применяются обычные для современных систем разработки пользовательского интерфейса подходы: обработка событий, прямое манипулирование атрибутами объектов и пр..

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

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

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

^ 3.Предлагаемые решения для организации взаимодействия DHTML-компонент

В предыдущих разделах были описаны особенности взаимодействия DHTML-компонент в Веб-приложении с насыщенным пользовательским интерфейсом, где применяется режим асинхронной «сборки» документов в программной среде клиента. Представлена идея использования опробованного в архитектуре MVC-Smalltalk метода организации связей между компонентами, который позволяет избежать трудностей, возникающих при обычном, «комбинаторном» варианте реализации такого взаимодействия.

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

механизм представления структуры приложения, который позволяет реализовать более эффективную и управляемую модель по сравнению с той, которая поддерживается в DHTML;

механизм представления состояния приложения (переменных приложения), который помимо функций общей памяти, разделяемой в контекстах всех документов (окон) приложения, обладает еще функцией регистрации изменений (change management);

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


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

^ 3.1.Модель программной структуры клиентского приложения

Одним из базовых инструментов DHTML-программирования, который разработчики активно используют при создании насыщенных интерфейсов Веб-приложений, являются средства визуальной компоновки документов на стороне клиента. Например, с помощью вложенных фреймовых окон (задаваемых посредством html-тегов frameset, frame и iframe) можно создавать составные документы, которые способны гораздо более рационально распоряжаться пространством внутри отдельного окна броузера по сравнению с обычными, простыми документами. В равной мере, осваивая возможности открытия дополнительных окон броузера (например, через обращение к функции window.open), можно эффективно использовать третье (оконное) измерение пользовательского интерфейса. В частности, именно эта техника часто используется в «настольных» системах для реализации сложных сценариев диалога с пользователем.

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

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