Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Паттерны представления данных в WEB





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

Функции Web-сервера состоят в интерпретации адреса URL запроса и передаче управления соответствующей программе (вариант, когда WEB-сервер считывает с диска и отправляет клиету обычный файл не рассматривается). Существует две основные формы представления программы Web-сервера - сценарий (script) и страница сервера (serverpage).

Сценарий состоит из функций или методов, предназначенных для обработки запросов HTTP. Типичными примерами могут служить сценарии CGI и сервлеты Java. Подобная программа способна выполнять практически все то же, что и традиционное приложение.

Сценарий часто разбивается на подпрогаммы и пользуется сторонними службами. Он получает данные с Web-страницы, проверяя строковый объект HTTP-запроса и вычленяя из него регулярные выражения; простота реализации подобных функций с помощью языка Perl снискали последнему славу одного из наиболее адекватных средств разработки сценариев CGI. В иных случаях, например при использовании сервлетов Java, прогрраммист получает доступ к информации запроса через интерфейс ключевых слов, что нередко значительно удобнее. Результатом работы Web-сервера служит другая - ответная - строка, образуемая сценарием с привлечением обычных функций поточного вывода.

Задача формирования кода HTML посредством команд поточного вывода не очень привлекательна для программистов, а непрограммистам она вообще не по силам, хотя они с удовольствием взялись бы за Web-дизайн с помощью других инструментов. Это естественным образом подводит к модели страниц сервера, где функции программы сводятся к возврату порции текстовых данных. Страница содержит текст HTML с "вкраплениями" исполняемого кода. Подобный подход, реализуемый, например, в PHP, ASP и JSP, особенно удобен, если требуется незначительная дополнительная обработка текста с учетом реакции пользователя.

Поскольку модель сценариев лучше подходит для интерпретации запросов, а схема страниц сервера - для форматирования ответов, вполне разумно применять их совместно. На самом деле это довольно старая идея, впервые реализованная в пользовательских интерфейсах на основе паттерна модель-представление-контроллер.

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



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

Основной довод в пользу применения решения модель-представление-контроллер состоит в том, что оно предусматривает полное отмежевание модели от Web-представления. Это упрощает возможности модификации существующих и добавления новых представлений. А размещение логики в отдельных объектах сценария транзакции (Transaction Script) и модели предметной области (Domain Model) облегчает их тестирование. Это особенно важно, когда в качестве представления используется страница сервера. Здесь наступает черед практического применения второго варианта толкования термина "контроллер". Во многи версиях пользовательского интерфейса объекты представленияотделяются от объектов домена промежуточным слоем объектов контроллера приложения (Application Controller), назначением которого является управление потоком функций приложения и выбор порядка демонстрации интерфейсных экранов. Контроллер приложения выглядит как часть слоя представления либо как самостоятельная "прослойка" между уровнями представления и предметной области. Контроллеры приложения могут быть реализованы независимо от какого бы то ни было частного представления, и тогда их удается использовать повторно для различных представлений.

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

 

Паттерн Model-View-Controller

Паттерн распределяет обработку взаимодействия с пользовательским интерфейсом между тремя участниками

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

Принцип действия

Типовое решение модель-представление-контроллер подразумевает выделение трех отдельных ролей. Модель - это объект, предоставляющий некотору информацию о домене. У модели нет визуального интерфейса, она содержит в себе все данные и поведение, не связанные с пользовательским интерфейсом. В объектно-ориентированном кон-тексте наиболее "чистой" формой модели является объект модели предметной области (Domain Model). В качествемодели можно рассматривать и сценарий транзакции (Transaction Script), если он не содержит в себе никакой логики, связанной с пользовательским интерфейсом. Подобное определение не очень расширяет понятие модели, однако полностью соответствует распределению ролей в рассматриваемом типовом решении.

 

Рисунок 3.20 Структура паттерна MVC

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

Говоря о типовом решении MVC, нельзя не подчеркнуть два принципиальных типа разделения: отделение представления от модели и отделение контроллера от представления.

Отделение представления от модели - это один из фундаментальных принципов проектирования программного обеспечения. Наличие подобного разделения весьма важно по ряду причин.

  • Представление и модель относятся к совершенно разным сферам программирова ния. Разрабатывая представление, вы думаете о механизмах пользовательского интерфейса и о том, как сделать интерфейс приложения максимально удобным для пользователя. В свою очередь, при работе с моделью ваше внимание сосредоточе но на бизнес-политиках и, возможно, на взаимодействии с базой данных. Очевидно, при разработке модели и представления применяются разные (совершенно разные!) библиотеки. Кроме того, большинство разработчиков специализируются только в одной из этих областей.
  • Пользователи хотят, чтобы, в зависимости от ситуации, одна и та же информация могла быть отображена разными способами. Отделение представления от модели позволяет разработать для одного и того же кода модели несколько представлений, а точнее, несколько абсолютно разных интерфейсов. Наиболее наглядно данный подход проявляется в том случае, когда одна и та же модель может быть представлена с помощью толстого клиента, Web-обозревателя, удаленного API или интер фейса командной строки. Даже в пределах одного и того же Web-интерфейса в разных местах приложения одному и тому же покупателю могут соответствовать разные страницы.
  • Объекты, не имеющие визуального интерфейса, гораздо легче тестировать, чем объекты с интерфейсом. Отделение представления от модели позволяет легко протестировать всю логику домена, не прибегая к таким "ужасным" вещам, как средства написания сценариев для поддержки графического интерфейса пользователя.

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

Кроме того, это означает, что изменение представления не требует изменения модели. Данный принцип тесно связан с распространенной проблемой. При использовании толстого клиента с множеством диалоговых окон на экране могут одновременно находиться несколько представлений одной и той же модели. Если пользователь внесет изменения в модель посредством одного представления, эти изменения должны быть отражены и во всех остальных представлениях. Чтобы это было возможным при отсутствии двунаправленной зависимости, необходимо реализовать типовое решение наблюдатель (Observer). В этом случае представление будет выполнять роль "наблюдателя" за моделью: как только модель будет изменена, представление генерирует соответствующее событие и все остальные представления обновляют свое содержимое.

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

О данном решении вспомнили только при появлении Web-интерфейсов, где отделение контроллера от представления оказалось чрезвычайно полезным. Тот факт, что в большинстве инфраструктур пользовательских интерфейсов не проводилось разделение на представление и контроллер, привел к множеству неверных толкований паттерна MVC. Да, наличие модели и представления очевидно, но где же контроллер? Многие решили, что контроллер находится между моделью и представлением, как в контроллере приложения (Application Controller). Данное заблуждение еще более усугубил тот факт, что в обоих названиях фигурирует слово "контроллер". Между тем, несмотря на все полож тельные качестваконтроллера приложения, он ничем не похож на контроллер MVC.

Назначение

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

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

Паттерн Page Controller

Контроллер страниц (Page Controller). Объект, который обрабатывает запрос к конкретной Web-странице или выполнение конкретного действия на Web-сайте.

 

Рисунок 3.21. Структура паттерна Page Controller

Большинство пользователей Internet когда-либо сталкивались со статическими HTML-страницами. Когда посетитель сайта запрашивает статическую страницу, он передает Web-серверу имя и путь к HTML-документу, который хранится на этом сервере. Ключевым моментом здесь является то, что каждая страница Web-сайта представлена на сервере отдельным документом. С динамическими страницами дело обстоит далеко не так просто из-за более сложных отношений между именами путей и соответствующими файлами. Несмотря на это, простая модель, при которой одному пути соответствует один документ, обрабатывающий запрос, может быть применена и здесь.

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

Принцип действия

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

Контроллер страниц может быть реализован в виде сценария (сценария CGI, сервлета и т.п.) или страницы сервера (ASP, PHP, JSP и т.п.). Использование страницы сервера обычно предполагает сочетание в одном файле контроллера страниц и представления по шаблону (Template View). Это хорошо для представления по шаблону, но не очень подходит для контроллера страниц, поскольку значительно затрудняет правильное структурирование этого компонента. Данная проблема не столь важна, если страница применяется только для простого отображения информации. Тем не менее, если использование страницы предполагает наличие логики, связанной с извлечением пользовательских данных или выбором представления для отображения результатов, страница сервера может заполниться кошмарным кодом "скриптлета", т.е. внедренного сценария. Чтобы избежать подобных проблем, можно воспользоваться вспомогательным объектом (helper object). При получении запроса страница сервера вызывает вспомогательный объект для обработки всей имеющейся логики. В зависимости от ситуации, вспомогательный объект может вернуть управление первоначальной странице сервера или же обратиться к другой странице сервера, чтобы она выступила в качестве представления. В этом случае обработчиком запросов является страница сервера, однако большая часть логики контроллера заключена во вспомогательном объекте.

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

Ниже перечислены основные обязанности контроллера страниц.

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

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

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

Назначение

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

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

страниц сервера, а более сложные случаи — с применением вспомогательных объектов.

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

Паттерн Front Controller

Контроллер запросов (Front Controller). Контроллер, который обрабатывает все запросы к Web-серверу.

 

Рисунок 3.22 Структура паттерна Front Controller

Обработка запросов к Web-сайтам со сложной структурой подразумевает выполнение большого количества аналогичных действий. Это проверка безопасности, обеспечение поддержки интернационализации и открытие специальных представлений для особых категорий пользователей. Если поведение входного контроллера будет разбросано по нескольким объектам, это приведет к дублированию большей части кода. Кроме того, это значительно затруднит изменение поведения контроллера во время выполнения.

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

Принцип действия

Контроллер запросов обрабатывает все запросы, поступающие к Web-сайту, и обычно состоит из двух частей: Web-обработчика и иерархии команд. Web-обработчик - это объект, который выполняет фактическое получение POST или GET запросов, поступивших на Web-сервер. Он извлекает необходимую информацию из адреса URL и входных данных запроса, после чего решает, какое действие необходимо инициировать, и делегирует его выполнение соответствующей команде (рис. 3.23).

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

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

Рисунок 3.23 Принцип работы контроллера запросов

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

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

Назначение

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

Во-первых, Web-сервер должен быть настроен на использование только одного контроллера запросов; всю остальную работу по распределению запросов будет выполнять Web-обработчик. Это значительно облегчит конфигурирование Web-сервера . Использование динамического выбора команд позволяет добавлять новые команды без каких-либо изменений. Кроме того, динамические команды облегчают переносимость, так как от вас требуется лишь зарегистрировать обработчик в настройках сервера. Поскольку для выполнения каждого запроса создаются новые экземпляры классов команд, вам не придется беспокоиться о том, чтобы они функционировали в отдельных потоках. Это позволит избежать всех неприятностей, связанных с многопоточным программированием; тем не менее вам придется следить за отсутствием совместного использования других объектов, таких, как объекты модели.

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

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

Паттерн Template View

Представление по шаблону (Template View). Преобразует результаты выполнения запроса в формат HTML путем внедрения маркеров в HTML-страницу.

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

Для редактирования статических HTML-страниц (тех, содержимое которых не изменяется от запроса к запросу) можно использовать замечательные текстовые редакторы, работающие по принципу WYSIWYG (What You See Is What You Get — что видишь на экране, то и получишь при печати). Даже тем, кто предпочитает самые примитивные редакторы, набирать текст и дескрипторы намного приятнее, чем заниматься конкатенацией строк в коде программы.

 

Рисунок 3.24 Структура паттерна Template View

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

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

Принцип действия

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

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

Вставка маркеров

Существует несколько способов внедрения маркеров в HTML-страницу. Один из них - это использование HTML-подобных дескрипторов. Данный способ хорошо подходит для редакторов, работающих по принципу WYSIWYG, поскольку они распознают элементы, заключенные в угловые скобки (<>), как специальное содержимое и поэтому игнорируют их либо обращаются с ними иначе, чем с обычным текстом. Если дескрипторы удовлетворяют правилам форматирования языка XML, для работы с полученным документом можно использовать средства XML (разумеется, при условии, что результирующий документ HTML является документом XHTML).

Еще один способ внедрения динамического содержимого - вставка специальных текстовых маркеров в тело страницы. В этом случае текстовые редакторы WYSIWYG будут воспринимать вставленные маркер как обычный текст. Разумеется, содержимое маркеров от этого не изменится, однако может быть подвергнуто разнообразным назойливым операциям, например проверке орфографии. Тем не менее данный способ позволяет обойтись без запутанного синтаксиса HTML/XML.

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

Одной из наиболее популярных форм представления по шаблону является страница сервера (serverpage) - ASP, JSP или PHP. Вообще говоря, страницы сервера - это нечто большее, чем представление по шаблону, поскольку они позволяют внедрять в страницу элементы программной логики, называемые скриптлетами (scriptlets). Однако, скриплеты в трудно назвать удачным решением. Наиболее очевидный недостаток внедрения в страницу сервера множества скриптлетов состоит в том, что ее могут редактировать исключительно программисты. Данная проблема особенно критична, если проектированием страницы занимаются графические дизайнеры. Однако самые существенные недостатки скриптлетов связаны с тем, что страница - далеко не самый подходящий модуль для программы. Даже при использовании объектно-ориентированных языков программирования внедрение кода в текст страницы лишает вас возможности применять многие средства структурирования, необходимые для построения модулей как в объектно-ориентированном, так и в процедурном стиле.

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

Вспомогательный объект

Чтобы избежать использования скриптлетов, каждой странице можно назначить собственный вспомогательный объект (helper object). Этот объект будет содержать в себе всю фактическую логику домена, а сама страница - только вызовы вспомогательного объекта, что значительно упростит структуру страницы и максимально приблизит ее к "чистой" форме представления по шаблону. Более того, это обеспечит возможность "разделения труда", при котором непрограммисты смогут спокойно заняться редактированием страницы, а программисты - сосредоточиться на разработке вспомогательного объекта. В зависимости от используемого средства, все "шаблонное" содержимое страницы зачастую можно свести к набору HTML/XML - дескрипторов, что повысит согласованность страницы и сделает ее более пригодной для поддержки стандартными средствами.

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

Условное отображение

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

 

<IF condition = "$a>отобразить__что_нибудь</IF>.

 

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

Из всего сказанного выше можно понять, что использование условных дескрипторов лучше избегать. Разумеется, это не всегда возможно, однако вы должны постараться придумать что-то более подходящее к потребностямконкретного приложения, чем универсальный дескриптор <IF>.

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

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

Чтобы управление HTML-разметкой осталось в руках дизайнера страниц, необходимо воспользоваться условными дескрипторами. В такой ситуации очень важно не опуститься до применения простого дескриптора <IF>. Удачным решением является применение дескрипторов, направленных на выполнение определенных действий. Например, вместо дескриптора

 

<IF expression = "isHighSelling()"><B></IF>

<property name = "price"/>

<IF expression = "isHighSelling () "></Bx/IF>

 

можно применить дескриптор

<highlight condition = "isHighSelling" style = "bold">

<property name = "price"/>

</highlight>

 

И в том и в другом случае очень важно, чтобы проверка условия выполнялась на основе единственного булева свойства вспомогательного объекта. Наличие на странице более сложных условных выражений будет означать перенесение логики на саму страницу. Еще одним примером условного поведения является отображение той или иной информации в зависимости от используемого в системе регионального стандарта. Предпо-ложим, что некоторый текст должен отображаться на экране только для пользователей из ША или Канады. В этом случае вместо универсального дескриптора

 

<IF expression= " locale='US'>текст >

 

рекомендуется использовать дескриптор вида

 

<locale includes = "US ">текст</locale>

 

Итерация

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

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

Обработка страницы

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









Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2018 zdamsam.ru Размещенные материалы защищены законодательством РФ.