0 11.3K ru

MV-паттерны для проектирования веб-приложений

 

MVC — Model-View-Controller

MVC

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

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

Описание компонентов MVC (Model, View и Controller):

Model
Модель – это данные вашего приложения, логика их получения и сохранения. Зачастую это модель предметной области (domain model), основанная на базе данных или на результатах от веб-сервисов. В некоторых случаях domain model хорошо проецируется на то, что вы видите на экране. Но иногда перед использованием ее необходимо адаптировать, изменить или расширить.

View
View отвечала за отображение UI на экране. Без библиотек виджетов, это означало самостоятельную отрисовку блоков, кнопок, полей ввода и т. п. View также может наблюдать за моделью и отображать данные из неё.

  • Controller
    Controller обрабатывает действия пользователя и затем обновляет Model или View. Если пользователь взаимодействует с приложением (нажимает кнопки на клавиатуре, передвигает курсор мыши), контроллер получает уведомление об этих действиях и решает, что с ними делать.

MVP

Model-View-Presenter (MVP) — шаблон проектирования, производный от MVC, который используется в основном для построения пользовательского интерфейса. Элемент Presenter в данном шаблоне берёт на себя функциональность посредника (аналогично контроллеру в MVC) и отвечает за управление событиями пользовательского интерфейса (например, использование мыши) так же, как в других шаблонах обычно отвечает представление.

MVP

Model
Это данные вашего приложения, логика их получения и сохранения. Зачастую она основана на базе данных или на результатах от веб-сервисов. В некоторых случаях потребуется ее адаптировать, изменить или расширить перед использованием во View.

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

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

 

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

Существует два варианта этого паттерна: Passive View и Supervising Controller.

Passive View

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

Пример PassiveView:

public PersonalDataView : UserControl, IPersonalDataView
  {
      TextBox _firstNameTextBox;

      public string FirstName
      {
          get
          {
              return _firstNameTextBox.Value;
          }
          set 
          {
              _firstNameTextBox.Value = value;
          }
      }
  }

Как вы можете видеть, требуется писать довольно много кода как во View, так и в презентере. Тем не менее, это сделает взаимодействие между ними более тестируемым.

Supervising Controller

В этом варианте MVP представление знает о модели и отвечает за связывание данных с отображением. Это делает общение между презентером и View более лаконичным, но в ущерб тестируемости взаимодействия View-Presenter. 

Пример Supervising Controller:

 public class PersonalDataView : UserControl, IPersonalDataView
  {
      protected TextBox _firstNameTextBox;

      public void SetPersonalData(PersonalData data)
      {
          _firstNameTextBox.Value = data.FirstName;
      }

      public void UpdatePersonalData(PersonalData data)
      {
          data.FirstName = _firstNameTextBox.Value;
      }
  }

 

MVVM

MVVM

Шаблон Model-View-ViewModel (MVVM) — применяется при проектировании архитектуры приложения. Первоначально был представлен сообществу Джоном Госсманом в 05 году как модификация шаблона Presentation Model. MVVM ориентирован на современные платформы разработки, такие как Windows Presentation Foundation, Silverlight от компании Microsoft

ViewModel не может общаться со View напрямую. Вместо этого она представляет легко связываемые свойства и методы в виде команд. View может привязываться к этим свойствам, чтобы получать информацию из ViewModel и вызывать на ней команды (методы). Это не требует того, чтобы View знала о ViewModel. XAML Databinding использует рефлексию, чтобы связать View и ViewModel. Таким образом, вы можете использовать любую ViewModel для View, которая предоставляет нужные свойства.

Особенности MVVM:

Вы получаете полностью тестируемую логическую модель вашего приложения.

  • MVVM заставляет работать с View одновременно двумя путями: через databinding и через методы View.
  • С MVVM нельзя красиво решить проблему состояний (необходимости сохранения вызова метода View, вызванного когда View была отсоединена от ViewModel).

Front Controller

front controller

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

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

Page Controller (Контроллер страницы)

page controller

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

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

Основные обязанности Page Controller:

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

Application Controller

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

application controller

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

Назначение

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

Template View (Шаблонизатор)

Template View (Шаблонизатор)

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

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

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

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

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

Пример: при обработке шаблона, области, помеченные специальными маркерами (на картинке тег <jsp:.../>) заменяются результатами вызовов методов helper'a.

Transform View

transform view

Представление, которое поочередно обрабатывает элементы данных домена и преобразует их в код HTML.

Когда выполняются запросы к БД, вы получаете данные, но этого не достаточно, чтобы отобразить нормальную web-страницу. Задача вида (view) в паттерне MVC - формировать данные в web-страницу. Использование Transform View подразумевает преобразование, когда на входе есть модель, а на выходе HTML.

Пример: на входе преобразователя модель, содержащая имя альбома (album name) и имя артиста (artist name). На выходе - код <a href="http://exapmle.com/music/album_name/artist_name">artist name</a>

Two Step View (Двухшаговая шаблонизация)

Two Step View (Двухшаговая шаблонизация)

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

Если web-приложение состоит из множества страниц, необходим единый вид и единая структура сайта. Если каждая страница выглядит по своему, получится сайт, который будет непонятным для пользователя. Также возможна ситуация, когда нужно сделать глобальные изменения на всём сайте (например поменять заголовок), но при использовании Template View или Transform View возникают трудности, потому что код представления дублируется от страницы к странице и надо исправлять его во всех файлах.

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

Выводы

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

Comments:

Please log in to be able add comments.