Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ajax в действии

.pdf
Скачиваний:
92
Добавлен:
01.05.2014
Размер:
6.34 Mб
Скачать

Глава 2. Знакомство с Ajax

95

2.6. Отличия Ajax от классических технологий

Несмотря на то что CSS, DOM, асинхронные запросы и JavaScript являются неотъемлемыми компонентами Ajax, эти технологии можно использовать независимо.

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

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

Ajax отличается от других подходов к созданию Web-приложений не используемыми технологиями, а моделью взаимодействия, которая становится возможной благодаря применению этих технологий. Модель взаимодействия Web плохо подходит для создания независимых приложений, и как только появилась возможность обойти ограничения этой модели, появились и новые перспективы в разработке интерфейсов.

Очевидны два уровня, на которых целесообразно применять Ajax и ряд ситуаций, в которых есть смысл обращаться к классическому подходу, основанному на использовании Web-страниц. Проще всего создавать на базе Ajax отдельные компоненты и включать их в состав Web-страницы посредством фрагментов сценариев. В качестве примеров подобных компонентов можно привести обновляемые данные о котировках акций, интерактивный календарь, окно для обмена сообщениями в реальном времени. Таким образом, на классических Web-страницах могут располагаться "островки", реализующие поведение, подобное интерфейсу обычных приложений для настольных систем (рис. 2.6). Большинство попыток обратиться к Ajax при разработке средств Google вполне укладываются в эту модель. Заполнение поля в Google Suggest и карта в Google Maps — хорошие примеры интерактивных элементов в составе статического документа.

96 Часть I. Новый взгляд на Web-приложение

Рис. 2.6. Простое Ajax-приложение, которое представляет собой Web-страницу с "островками", реализующими интерактивные функции

Дальнейшим продвижением применения Ajax может стать создание системы, в которой фрагменты, ориентированные на приложение и документ, присутствуют на равных правах (рис. 2.7). Продукт, полученный в результате следования такому подходу, можно сравнить с приложением для настольной системы или даже с диспетчером окон. Этой модели соответствует Google GMail, где отдельные сообщения воспроизводятся как документы в составе интерактивной структуры.

Изучение новых технологий — приятное занятие. Несмотря на то что составные части Ajax уже известны разработчикам, интересно попробовать, как они будут работать совместно. Мы привыкли считать Web-приложение чем-то вроде повествования, в ходе которого мы ведем пользователя от одной странице к другой по предопределенному сценарию. Следуя новому подходу, мы предоставляем пользователю возможность лучше контролировать те вопросы, для решения которых и создавалось приложение.

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

Глава 2. Знакомство cAjax

97

Рис. 2.7. Более сложное Ajax-приложение, представляющее собой интерактивную систему, в которой присутствуют элементы содержимого, ориентированного на документ. Эти элементы могут быть загружены или определены из программы

ся очень быстро, и все мы придаем большое значение приобретению новых навыков. Однако избавление от старых привычек не менее важно.

2.7. Резюме

В данной главе мы рассмотрели четыре составные части Ajax.

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

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

Вы узнали, как работать с объектом XMLHttpRequest и более старыми средствами: XmlDocument и IFrame. В настоящее время можно услышать мно-

98 Часть I. Новый взгляд на Web-приложение

го хвалебных отзывов об объекте XMLHttpRequest, позволяющем организовать взаимодействие с сервером. Однако I Frame также предоставляет подобные возможности, и в некоторых случаях удобно воспользоваться именно этим элементом. Зная, как работать с ними обоими, вы несомненно повысите свою квалификацию Web-разработчика. В главе 5 мы подробно обсудим взаимодействие клиента и сервера.

Инаконец, мы рассмотрели объединение основных составляющих Ajax,

врезультате которого удалось получить нечто большее, чем сумму составных частей. Ajax подходит не только для решения частных задач, например, реализации компонентов, включаемых на Web-страницу, которая при отсутствии их была бы статической. Данный подход можно смело применять как основу для создания интерактивного пользовательского интерфейса, в котором содержались бы лишь отдельные "островки" статических данных. Для того чтобы средства Ajax перешли с второстепенных на основные роли, надо создать большой объем JavaScript-кода, который мог бы надежно работать

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

2.8. Ресурсы

Для тех, кто стремится глубже изучить каскадные таблицы стилей, мы рекомендуем узел CSS Zen Garden (http://www.csszengarden.com/), стили которого могут изменяться множеством способов, причем для получения результата не используются никакие другие средства, кроме CSS.

Эрик Мейер (Eric Meyer) интенсивно использует CSS. Посетите его Webузел по адресу http://www.meyerweb.com/eric/css/. Blooberry (http:// www.blooberry.com) — еще один превосходный ресурс для тех, кому необходима информация по CSS.

С первыми решениями Ajax, использующими элементы IFrame, можно ознакомиться по адресу http://developer.apple.com/internet/webcontent /iframe.html.

Расширение Mozilla LiveHttpHeaders можно найти по адресу h t t p : / / livehttpheaders.mozdev.org/.

В книгах Денни Гудмена (Danny Goodman) Dynamic HTML: The Definitive Reference (O'Reilly, 2002) и JavaScript Bible (John Wiley, 2004) содержится обширный материал по работе с D0M. Кроме того, в них подробно описывается среда браузера.

На Web-узле W3Schools (http://www.w3schools.com/js/js_examples_3. asp) представлены интерактивные руководства по JavaScript.

Управление ко

Вэтой главе ...

Разработка и сопровождение сложных клиентов Ajax

Реструктуризация JavaScript-кода Ajax-приложения

Использование образов разработки

при создании Ajax-приложений

Использование архитектуры "модель-представление- контроллер" при создании серверных программ

всоставе Ajax-приложений

Общие сведения о библиотеках Ajax

независимых производителей

100Часть I. Новый взгляд на Web-приложение

Вглаве 2 мы обсудили основные технологии, составляющие инфраструктуру Ajax. Оказывается, что, пользуясь лишь давно известными нам средствами, можно написать превосходное Ajax-приложение, о котором мы давно мечтали. К сожалению, можно создать себе и массу проблем и получить

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

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

Ксчастью, подобные проблемы возникали уже на заре компьютерной эры и даже до ее начала. Разработчики нашли способ справляться со сложными проектами и держать в порядке коды большого объема. В этой главе мы рассмотрим базовые инструменты для работы с кодом, которые помогут вам создать Ajax-приложение, изменить его по требованию заказчика и при этом не задерживаться на работе после окончания рабочего дня.

Ajax отличается от DHTML не только способом применения уже известных технологий, но и масштабом их использования. В Ajax-приложении содержится гораздо больший объем JavaScript-кода, чем в классическом приложении. Кроме того, код присутствует в браузере в течение гораздо более длительного времени. Следовательно, возникает задача управления сложностью, которая не стояла перед специалистами, использовавшими DHTML.

В этой главе мы рассмотрим инструменты и приемы, позволяющие наводить порядок в коде программы. Важность этих средств зависит от сложности Ajax-приложения, которое вы создаете. Если вы собираетесь ограничиться созданием лишь простых продуктов, мы советуем вам пропустить материал книги вплоть до главы 9, в которой мы начнем рассмотрение программ, управляемых примерами. Если вы уже знакомы с принципами реструктуризации и образами разработки, перейдите к главам 4-6, в которых будет рассматриваться применение этих средств. В любом случае базовые понятия, рассматриваемые здесь, важны для управления JavaScript-кодом, и мы надеемся, что рано или поздно вы вернетесь к данной главе. В конце главы приведен обзор библиотек независимых производителей, ориентированных на Ajax, поэтому если вы ищете набор инструментов для своего проекта, обратитесь к разделу 3.5.

3.1. Порядок из хаоса

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

Глава 3. Управление кодом Ajax 101

Если код имеет ясную и понятную структуру, гораздо проще реализовы- Бать новые функции, а также модифицировать и удалять уже существующие. Если код выполнен неаккуратно, он, может быть, и соответствует текущим требованиям, но никто из команды разработчиков не представляет, почему же он все-таки работает.

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

Элементарные действия по реструктуризации уже описывались в главе 2, когда речь шла о размещении JavaScript, HTML-кода и таблиц стилей в отдельных файлах. Однако JavaScript-код считается длинным, если он превышает 120 строк и объединяет в себе низкоуровневые функции (например, поддержку запроса серверу) с фрагментами кода, управляющими объектами документа. При работе над большим проектом иметь один JavaScript-файл (равно как и один файл со стилями) крайне неудобно. Гораздо лучше создавать небольшие фрагменты кода, удобные для чтения и модификации, каждый из которых выполняет конкретную задачу. Такой подход принято называть распределением функций, или распределением ответственности

(separation of responsibilities).

Реструктуризация преследует и другую цель — идентификацию общих решений и приведение кода в соответствие конкретному образу разработки. Этот вопрос желательно обсудить подробнее.

3.1.1. Образы разработки

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

Такие шаблоны, отражающие опыт предшественников, принято называть образами разработки. Это понятие было введено в 1970-х годах в архитектуре, а в последние годы его начали применять и разработчики программного обеспечения. Образы разработки широко применяются при создании Javaпрограмм, предназначенных для выполнения на сервере, а корпорация Microsoft активно внедряет его в .NET Framework. Данный термин звучит внушительно, напоминает нечто, относящееся к "чистой науке", и бывает, что кто-то, не потрудившись разобраться в данном вопросе, применяет его лишь для того, чтобы произвести впечатление на собеседников. Многие неправильно истолковывают это понятие. На самом деле образ разработки — это описание способа решения задачи, связанной с разработкой программы. Благодаря применению образов разработки ряд абстрактных решений получили имена, а это упрощает их обсуждение и понимание.

102 Часть I. Новый взгляд на Web-приложение

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

Если вы давно занимаетесь разработкой серверных программ на Java, то, вероятно, скажете, что мы не сообщили вам ничего нового. Другие, возможно, подумают, что мы агитируем их применять нечто вроде блок-схем. В любом случае мы готовы услышать вопрос: какое отношение имеет вышесказанное к Ajax? Ответ прост: большое! Давайте выясним, какие выгоды может получить от реструктуризации программист, использующий Ajax.

3.1.2. Реструктуризация и Ajax

Мы уже говорили о том, что Ajax-приложения, как правило, содержат большой объем JavaScript-кода, который длительное время сохраняется

вбраузере.

Вклассическом Web-приложении сложный код находится на сервере и образы разработки применяются к серверным программам PHP, Java или .NET. Используя Ajax, мы должны применить те же средства к клиентскому коду.

Можно даже утверждать, что JavaScript-код больше нуждается в реструктуризации, чем программы, написанные на Java и С# . Несмотря на синтаксис, JavaScript больше напоминает такие языки, как Ruby, Python и даже Common Lisp, чем Java или С# . Он обеспечивает необычайную гибкость и богатые выразительные средства. Квалифицированный разработчик несомненно воплотит эти возможности в программу высокого качества, однако средний программист может не справиться с ними, в результате пострадает надежность программы. Языки, ориентированные на создание корпоративных приложений, такие как Java и С#, напротив, ориентированы на команду специалистов средней квалификации, состав которой может изменяться.

Опасность создать посредством JavaScript запутанный и сложный для восприятия код достаточно высока, и если этот код ориентирован не на одну Web-страницу, а на целое приложение, необходимо принимать меры для исключения такой возможности либо для уменьшения ее вероятности. Поэтому мы настаиваем на реструктуризации Ajax-программ и считаем, что она должна производиться более тщательно, чем это делается при работе с такими относительно "безопасными" языками, как Java и С# .

3.1.3. Во всем надо знать меру

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

Глава 3. Управление кодом Ajax 103

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

Подобную ситуацию описал Эрик Гамма (Erich Gamma), признанный специалист по образам разработки, в недавнем интервью (ссылка на него приведена в конце главы). Подобно тому как разработчик включает в свою программу целочисленные переменные, строки и массивы лишь там, где они необходимы, применять образы разработки надо только тогда, когда они нужны.

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

3.1.4. Реструктуризация в действии

На первый взгляд, преимущества реструктуризации кажутся очевидными, но программисты-практики, наверное, захотят увидеть их на конкретном примере. Потратим немного времени, чтобы применить процедуру реструктуризации к Ajax-коду, который был представлен в листинге 2.11. Как вы помните, мы определили функцию sendRequest(), предназначенную для передачи запросов серверу. Для извлечения объекта XMLHttpRequest эта функция обращается к initHttpRequest (), а обработка ответа производится посредством функции обратного вызова onReadyState (). Объект XMLHttpRequest был помещен в глобальную переменную, что позволило функции обратного вызова использовать его. Обработчик ответа, действующий по принципу обратного вызова, анализировал состояние объекта запроса и генерировал информацию, предназначенную для отладки.

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

104 Часть I. Новый взгляд на Web-приложение

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

В объектно-ориентированном программировании стандартным решением задач подобного рода является инкапсуляция требуемых функциональных возможностей в составе объекта. Объектные средства JavaScript позволяют нам сделать это. Мы назовем наш объект ContentLoader, поскольку он загружает данные с сервера. Каким должен быть этот объект? Наверное, он должен создаваться на основе URL ресурса, которому передается запрос. Нам также надо указать ссылку на произвольный обработчик обратного вызова, который будет выполнен при успешной загрузке документа. Необходима еще одна ссылка на обработчик, который получит управление при наличии ошибки. Обращение к объекту может выглядеть следующим образом:

var loader=new net.ContentLoader('mydata.xml', parseMyData);

где parseMyData — функция обратного вызова, соответствующая успешной загрузке документа. Код объекта ContentLoader показан в листинге 3.1. В нем были применены новые решения, которые мы обсудим ниже.

Листинг 3.1. Объект ContentLoader

//1 Объект пространства имен var net=new Object();

net.READY_STATE_UNINITIALIZED=O; net.READY_STATE_LOADING=1 ; net.READY_STATE_LOADED=2; net.READY_STATE_INTERACTIVE=3; net.READY_STATE_COMPLETE=4;

// 2 Конструктор net.ContentLoader=function(url,onload,onerror){

this.url=url; this.req=null ; this.onload=onload;

this.onerror=(onerror) ? onerror : this.defaultError; this.loadXMLDoc(url) ;

}

net.ContentLoader.prototype={

//3 Переименованная функция initXMLHttpRequest loadXMLDoc:function(url){

//4 Реструктуризированная функция loadXML

if (window.XMLHttpRequest){ this.req=new XMLHttpRequest() ;

} else if (window.ActiveXObject){

this.req=new ActiveXObject("Microsoft.XMLHTTP");

}

if (this.reqH try{

var loader=this; this.req.onreadystatechange=function(){ loader.onReadyState.call(loader);

}