современные методы разработки клиентских web

advertisement
СОВРЕМЕННЫЕ МЕТОДЫ РАЗРАБОТКИ КЛИЕНТСКИХ WEB-ПРИЛОЖЕНИЙ
Гулин Сергей Сергеевич (gulin.serge@gmail.com)
ЗАО «ИРТех», г. Самара
Аннотация
В статье раскрыта концептуальная часть реализации современных Web-приложений
в соответствии с шаблоном проектирования MVVM.
Современные тенденции рынка разработки клиентских приложений направлены в
сторону мобильных устройств. Тем не менее разработка клиентских Webприложений не стоит на месте, а активно развивается в направлении усложнения
пользовательских интерфейсов, как это уже было несколько лет назад среди
клиентских настольных приложений.
В настоящий момент применяются различные подходы к преодолению сложности
разработки качественных клиентских Web-интерфейсов. К таковым относят шаблоны
проектирования
слабосвязанного
взаимодействия
слоя
бизнес-логики
и
отображения, известные как MVC (Model-View-Controller) и MVVM (Model-ViewViewModel) [1].
Основное отличие этого подхода от классического заключается в перераспределении
ответственности между клиентом и сервером. Если ранее за отображение всей
информации отвечала серверная сторона, то с разработкой Ajax [2] это стало не так.
Доля ответственности за отображение наполнения страницы появилась и у клиента.
Это изменение поля ответственности привело к долгосрочному переходному
процессу, которым Ajax по своей сути и является. Следующие иллюстрации,
выполненные в соответствии с нотацией UML 2.0, показывают типовые сценарии
взаимодействия клиента и сервера в хронологическом порядке.
На рисунке 1 показано «классическое» взаимодействие, которое характеризуется
использованием HTTP-глаголов POST (на рисунке не отображен) и GET для
получения HTML-страниц целиком. Такое взаимодействие не требует поддержки
JavaScript со стороны браузера, отличается высокой стабильностью реализаций
среди различных Web-серверов и браузеров. Все браузеры, которые были когдалибо выпущены, поддерживают такое взаимодействие. У этого подхода есть ряд
недостатков, которые и привели его к модификации в будущем:
1. высокая нагрузка на сервер в виде генерации HTML-страниц;
2. высокая избыточность передаваемых данных;
3. высокое совокупное время отклика системы на единичную операцию со
стороны пользователя.
Сервер
Браузер
GET: /
HTML-страница
GET: /page2
HTML-страница
Рисунок 1. «Классическое» взаимодействие
С целью решения выше обозначенных проблем компания Google ввела новую
технологию, Ajax. Суть Ajax заключается в частичном обновлении HTML-страницы и
передаче HTML-фрагмента от сервера к клиенту. Впоследствии HTML-фрагмент был
заменен на XML-код с целью ограничения ответственности передаваемых данных за
отображение. Типовой сценарий выполнен на иллюстрации ниже:
Сервер
Браузер
GET: /
HTML-страница
GET: /contacts/1
HTML-фрагмент
Рисунок 2. Передача фрагментов HTML-страниц.
Стоит отметить особую роль языка JavaScript в этом качественном изменении,
которое отображено на рисунке 2. Именно с его помощью осуществляется
обновление части страницы, отправка запроса, обработка ответа и формирование
отображения данных при необходимости. Такое новое применение JavaScript
обозначило высокие требования к производительности его интерпретаторов:
формирование отображения и вставки DOM-элементов является затратной
операцией. Тем не менее этот подход решает проблемы нагрузки на сервер по
генерации HTML, радикально сокращает избыточность передаваемых данных и в
случае высокой производительности вычислительной техники клиента позволяет
достичь быстрой реакции пользовательского интерфейса. Первым Webприложением, которое начало использовать подход, описанный выше, считается
почтовый клиент Gmail от компании Google [2].
Тем не менее подход передачи фрагментов HTML-страниц или XML-документов с их
последующей пост-обработкой в виде генерации представления и вставки в дерево
DOM не лишен недостатков. Как часто бывает в индустрии разработки ПО,
достигаются цели производительности и начинают преследоваться цели уменьшения
стоимости кодирования и поддержки.
Можно проверить решение рисунка 2 на предмет хорошего компонентного дизайна и
убедиться, что по крайней мере одну ответственность реализуют браузер и Webсервер: генерацию отображения данных. Именно эта ответственность [4] вносит
дублирование логики как на стороне клиента, так и на стороне сервера, что с
высокой долей вероятности приведет к появлению «спагетти»-кода, поддержка
которого не сможет окупиться в будущем.
При большом количестве фрагментов реализация механизма на сервере,
позволяющего отправлять данные как в составе целой страницы, так и отдельными
фрагментами, будет нетривиальной, что повышает риски со стороны сервера. С
клиентской стороны риски также становятся высокими из-за нетривиальной
реализации механизма эффектов, допускающего изъятие DOM-элемента и вставку
на его место нового, являющегося результатом Ajax-запроса.
Борьба с эффектом, описанным выше, привела к появлению целого ряда различных
практик и способов организации кода, позволяющих управлять сложностью и
стоимостью поддержки Web-приложения [4]. К ним можно отнести технологии и
библиотеки последнего времени, например, такие как: REST, JSON, CoffeeScript,
ASP.NET MVC, ServiceStack, Angular.JS [7], Ruby on Rails и многие другие. Все эти
инструменты так или иначе в своей основе используют принцип разделения
ответственности, где каждый занимает определенную роль. В свою очередь,
шаблоны проектирования слабосвязанного взаимодействия MVC и MVVM являются
концептуальной реализацией принципа разделения ответственности, что выводит их
на фундаментальный уровень применения [3].
На рисунке 3 изображен объектный обмен данных, характерный для современных
Web-приложений, которые будут рассмотрены далее. Его особенностями являются:
1. запрос корня приложения приводит к получению уже заранее
скомпилированной, подготовленной статичной Web-части в виде набора,
состоящего из HTML-страницы, файлов JavaScript и CSS-стилей;
2. последующий обмен данными выглядит в виде передачи JSON-объектов
между браузером клиента и сервером, в качестве транспорта используется
REST-интерфейс.
Сервер
Браузер
GET: /
HTML-страница (статичная)
GET: /contacts/1
JSON-объект
Рисунок 3. Объектный обмен данных
Приведенный выше пример соответствует современной концепции разработки Webприложений, которая носит название SPA (Single-Page Application). Множество
библиотек и продуктов используют ее в своей работе, к таким относятся Sencha,
Dojo, Angular.JS, Backbone. Этот подход зарекомендовал себя с лучшей стороны по
организации кода приложения, уменьшению издержек на его поддержку и
обеспечению высокой гибкости к изменениям приложения, его частей.
Тем не менее он не лишен недостатков. Основная претензия пользователей таких
приложений к разработчикам заключается в накапливающемся времени отклика: по
истечении некоторого промежутка времени работы с приложением интерфейс
пользователя все медленнее и медленнее начинает реагировать на действия
пользователя. Для ликвидации этой задержки требуется перезапуск страницы с
приложением в браузере, что не всегда может быть комфортно для пользователя.
Авторы статьи считают, что радикальным решением этой проблемы был бы отказ от
реализации всего приложения в виде SPA. Основная мысль заключается в
разделении большого приложения на малые секции, которые можно было бы
реализовать уже в виде отдельных SPA. Такой подход позволил бы найти
компромисс между необходимостью перезагрузки страницы браузера с целью
сохранения времени отклика на приемлемом уровне, и в то же время позволил бы
гибко сочетать преимущества SPA перед классическим подходом. Важно отметить,
что разделение на секции выполняется до непосредственного выполнения
приложения. Сохраняются все преимущества применения кеширования статического
содержимого и разделения кода логики отображения между клиентом и сервером,
которые применяются в SPA. Это решение и его подобные авторы статьи предлагают
называть «LSPA» от Large Single-Page Application. На рисунке 4 показана разница
реализации приложения по SPA и LSPA:
Рисунок 4. Реализации приложения по LSPA и SPA на уровне компонент
Как видно из рисунка выше, Web-приложение по LSPA представляет собой
композицию из малых частей в виде SPA. Такой подход хорошо сочетается с
принципом единой ответственности и принципом высокой связности. Стоит отметить,
что на рисунке отмечена специальная корневая секция («/») как равноправная часть
всего LSPA. Решение выше позволяет находить компромиссное решение между
высокой скоростью отклика отдельных частей приложения и скоростью отклика всего
приложения. Также не стоит преуменьшать роль возможности выполнения
декомпозиции, что позволяет справляться со сложностью реализации сложных
интерфейсов пользователя.
Рассмотренный в статье подход позволяет радикально изменить взгляд на
сложность разработки больших и «толстых» клиентов на HTML. Авторами
представлена концепция LSPA, позволяющая реализовать RIA на JavaScript.
Литература
1. Martin Fowler. Patterms of Enterprise Application Architecture. Addison-Wesley
Professional, 2002. – 560 с.
2. Дейв Крейн, Эрик Паскарелло, Даррен Джеймс. AJAX в действии: технология –
Asynchronous JavaScript and XML = Ajax in Action. — М.: Вильямс, 2006. –
С. 640. – ISBN 1-932394-61-3
3. Эванс, Эрик. Предметно-ориентированное проектирование (DDD).: Пер. с англ. –
М.: ООО «И.Д. Вильямс», 2011. – 448с.: ил.
4. Мурадов Мурад Доступно о SOLID [Электронный ресурс] – Режим доступа:
http://muradovm.blogspot.ru/2012/03/solid.html.
5. Bill Venners Orthogonality and the DRY Principle [Электронный ресурс] – Режим
доступа: http://www.artima.com/intv/dry.html.
Download