Модель контроллер представление: MVC vs MVP vs MVVM / Хабр

Содержание

MVC — модель-представление-контроллер

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

Основная цель применения MVC состоит в разделении данных и бизнес-логики от визуализации. За счет такого разделения повышается возможность повторного использования программного кода: например, добавить представление данных какого-либо существующего маршрута не только в виде HTML, но и в форматах JSON, XML, PDF, XLSX становится очень просто и не требует исменений слоя бизнес-логики исходного маршрута. Также упрощается и сопровождение программного кода: внесение изменений во внешний вид, например, не отражаются на бизнес-логике, а изменения бизнес-логики не затрагивают визуализацию.

Концепция MVC разделяет данные, представление и обработку действий пользователя на компоненты:

  • Модель / Model — предоставляет собой объектную модель некой предметной области, включает в себя данные и методы работы с этими данными, реагирует на запросы из контроллера, возвращая данные и/или изменяя своё состояние. При этом модель не содержит в себе информации о способах визуализации данных или форматах их представления, а также не взаимодействует с пользователем напрямую.
  • Представление / View — отвечает за отображение информации (визуализацию). Одни и те же данные могут представляться различными способами и в различных форматах. Например, коллекцию объектов при помощи разных представлений можно представить на уровне пользовательского интерфейса как в табличном виде, так и списком; на уровне API можно экспортировать данные как в JSON, так в XML или XSLX. 
  • Контроллер / Controller — обеспечивает связь между пользователем и системой, использует модель и представление для реализации необходимой реакции на действия пользователя.
    Как правило, на уровне контроллера осуществляется фильтрация полученных данных и авторизация — проверяются права пользователя на выполнение действий или получение информации.

Альтернативные названия паттерна MVC:

  • model-view-controller
  • модель-представление-поведение
  • модель-представление-контроллер
  • модель-вид-контроллер

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

Использование паттерна MVC также позволяет следовать принципам SOLID в ООП и принципу DRY.

Программа Model-View-Controller MVC — что это, особенности и описание

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

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

Основные типы функциональности архитектуры

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

  1. Код модели обычно отражает реальные вещи. Этот код может содержать необработанные данные или определять основные компоненты приложения. Например, если пользователь создавал приложение Todo, код модели определял бы, что такое «задача» и что такое «список», поскольку это основные компоненты данного приложения.
  2. Вид, или представление — просмотр кода состоит из всех функций, которые непосредственно взаимодействуют с пользователем. Это код, который делает приложение красивым и в противном случае определяет, как пользователь видит и взаимодействует с ним.
  3. Контроллер действует как связь между моделью и представлением, принимая пользовательский ввод и решая, что с ним делать. Это мозг приложения и связывает модель и представление. Контроллер считают «средним уровнем». Он взаимодействует с пользователем, собирая данные, контактирует с моделью, получая необходимые данные, а затем с представлением, чтобы ответить пользователю.

Когда пользователь выполняет какое-либо действие, он сначала переходит к контроллеру. Он будет принимать любые данные, например, $_GET, $_POST переменные в PHP, и определять, что делать с этими данными.

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

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

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

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

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

Структура организации кода

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

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

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

Структура ASP.NET Core MVC — это легкая среда представления. Отличается открытым исходным кодом. Она высоко проверяемая, оптимизированная для использования с Asp Net Core MVC.

Архитектура MVC

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

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

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

Аналогия модели в современном мире

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

Например, приложение списка дел. Это приложение позволит пользователям создавать задачи и организовывать их в списки.

Модель в приложении ToDo может определить что «задача» есть и что «список» представляет собой набор задач. Код View определит, как выглядят ToDo и списки визуально. Задачи могут иметь большой шрифт или быть определенного цвета. Наконец, контроллер может определить, как пользователь добавляет задание или отмечает, когда оно завершено. Контроллер соединяет кнопку «Добавить» в «Модель» поэтому, когда пользователь нажимает «Добавить задачу», модель добавляет новую задачу.

Просто о шаблоне проектирования

Возможности MVC приложения можно показать в двух словах, на примере адресной книги. Модель представляет собой список Person объектов. Представление представляет собой окно графического интерфейса пользователя, которое отображает список людей. А контроллер обрабатывает такие действия, как «Удалить адрес человека», «Добавить адрес человека», «Электронная почта человека».

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

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

Основные зависимости элементов

Назначение контроллера — удалить зависимость вида от модели. Например, менеджер проекта требует от разработчика создать не только окно контактов, но еще одно, которое отображает все контакты только по их фотографиям. Фотографии должны быть в макете стола, по пять штук в строке. Для MVC эта задача довольно проста.

В настоящее время существует три класса:

  1. Person.
  2. PersonListController.
  3. PersonListView.

Необходимо создать два класса: PersonPhotoGridView и PersonPhotoGridController. Person класс остается тем же самым и легко вставляется в две различные точки зрения. Разработчик должен модифицировать Person класс для размещения нового PersonPhotoGridView и в конечном итоге усложняет модель (пример 3).

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

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

Принцип работы

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

Простой способ выполнения условия:

  1. Пользователь взаимодействует с представлением — нажатием на ссылку или отправкой формы.
  2. Контроллер обрабатывает ввод пользователя и передает информацию в модель.
  3. Модель получает информацию и обновляет ее состояние, добавляет данные в базу данных, например, вычисляет сегодняшнюю дату.
  4. Просмотр проверяет состояние Модели и отвечает соответственно, перечислив недавно введенные данные.
  5. Вид ожидает следующего взаимодействия пользователя.

Это простая концепция — Business Logic — вычисления логических процессов приложения. Например, бизнес-логика простого календаря должна была бы рассчитать, какая дата, какой день недели и какой день месяца, если нужно представить все дни в этом месяце. Или осуществлять обслуживание веб-контента с помощью Spring MVC, которая дает возможность строить приложение со статической домашней страницей, принимающей запросы HTTP GET.

Соблюдение принципа DRY

Многие фреймворки MVC используют систему шаблонов для обеспечения соблюдения принципа DRY, что делает его очень удобным для повторного использования кода без необходимости переписывания. Существуют рамки MVC, которые работают на Smarty или используют собственные механизмы шаблонов. Простым предупреждением является то, что некоторые движки шаблонов имеют довольно сложный синтаксис – программисту требуется проверить их, прежде чем начинать разработку.

Считается, что MVC – это еще одна очень хорошая реализация философии DRY (Do not Repeat Yourself). По сути, DRY используется Ruby on Rails и несколькими другими реализациями, а идея состоит в том, что программист пишет что-то один раз и один раз использует код. Принцип DRY определяется как «каждая часть должна иметь единое, однозначное, авторитетное представление внутри системы». Правильная реализация DRY означает, что изменение одного элемента системы не изменяет несвязанные элементы, что довольно логично.

Конвенция по конфигурации

Это парадигма дизайна, которая, по существу, пытается удалить количество решений, которые разработчик должен сделать. Это достигается путем создания структуры с соглашениями, которые обычно требуют все элементы. Разработчику нужно только изменить то, что действительно необходимо. Это довольно просто. Например, для формы, содержащей элементы, которые всегда требуются и имеют одинаковые значения. Форма имеет тег, который определяет действие, метод, имя, id и enctype. Например, если не нужно что-то менять, довольно легко получить имя формы, идентификатор и действие из URL-адреса.

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

Преимущества и недостатки метода

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

Преимущества MVC:

  1. Быстрый процесс разработки, поддерживает быстрое и параллельное развитие.
  2. С MVC один программист может работать над представлением, а другой может работать над контроллером для создания бизнес-логики.
  3. Приложение, разработанное с его применением, в три раза быстрее, чем приложение, разработанное с другими шаблонами разработки.
  4. Возможность предоставления нескольких видов.
  5. В MVC можно создавать несколько представлений.
  6. Копирование дубликатов очень ограничено, поскольку оно отделяет данные и логику от дисплея.
  7. Поддержка асинхронной технологии, которая помогает разработчикам разрабатывать быстро загружаемое приложение.
  8. Модификация не влияет на всю модель, потому что часть модели не зависит от части просмотров. Поэтому любые изменения в Модели не будут влиять на всю архитектуру.
  9. Шаблон NET MVC возвращает данные без применения какого-либо форматирования, поэтому одни и те же компоненты могут использоваться и вызываться для использования с любым интерфейсом.
  10. С помощью этой платформы очень легко разрабатывать URL-адреса, оптимизированные для SEO, для получения большего количества посещений из определенного приложения.

Недостатки MVC:

  1. Повышенная сложность.
  2. Неэффективность доступа к данным.
  3. Сложность использования MVC с современным пользовательским интерфейсом.
  4. Нужно несколько программистов.
  5. Требуется знание нескольких технологий. Разработчик знает код клиентской стороны и html-код.

Создание первого приложения

Можно разработать примеры ASP.NET MVC с соответствующей версией среды Visual Studio и .NET, используя MVC v5.2, 2017 Community и платформу .NET 4.6.

Порядок выполнения:

  1. Открыть программу Visual Studio 2017 и далее: Файл -> Создать > Проект.
  2. Разворачивают узел Visual C # и Web в левой части и далее выбирают asp net MVC в средней части.
  3. Вводят название своего проекта MyMVCApplication, можно указать любое подходящее имя для своего приложения.
  4. Устанавливают местоположение проекта, нажав «Обзор» и далее «ОК».
  5. В окне «Новое веб-приложение» находят asp MVC core.
  6. Изменяют аутентификацию, нажав соответствующую кнопку.
  7. Нажимают «ОК», чтобы MVC создал проект с использованием шаблона.
  8. Первое приложение готово.

Запускают проект в режиме отладки F5 или Ctrl + F5 без отладки.

Проект MVC framework включает JavaScript и файлы CSS bootstrap 3. 0 по умолчанию.

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

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

Таким образом, легко создать свое первое приложение core MVC с помощью Visual Studio 2013.

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

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

Принцип MVC в web — программировании

Принцип MVC у веб-программировании (Model — View — Controller, Модель — Представление(Вид) — Контроллер) — одна из наиболее удачных идей на сегодняшний день. Принцип MVC интуитивно понятен на первый взгляд, но не очень простой при углублении. Сначала рассмотрим, для чего он предназначен.

Принцип MVC, позволяет разделить реализацию логики приложения, внешний вид (графический интерфейс, GUI) и взаимодействие с пользователем.

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

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

Принцип MVC используют практически все современные фреймворки.

Рассмотрим подробнее компоненты.

Model (Модель) — содержит т.н. «бизнес-логику» — обработку и верификацию данных, обращения к базам данных, представляет внутреннее устройство системы. Модель не должна напрямую взаимодействовать с пользователем.

View (Вид, Представление) описывает внешний вид приложения.

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

Взаимосвязь можно посмотреть на диаграмме:

Источник изображения: http://www.wikipedia.org Требования к компонентам:

Модели:

  • должны содержать свойства, представляющие конкретные данные;
  • должны включать в себя бизнес-логику (например, правила валидации), чтобы убедиться в том, что данные соответствуют предъявленным требованиям;
  • могут содержать код для работы с данными.
Представления:
  • должны, главным образом, содержать разметку, такую как HTML, и простой PHP код, используемый для обхода, форматирования и отображения данных;
  • не должны напрямую обращаться к базе данных. Этим должны заниматься модели;
  • не должны напрямую обращаться к $_GET, $_POST и другим переменным, получаемым из запроса пользователя. Эту задачу должен выполнять контроллер. Представления должны использоваться только для оформления данных, полученных от контроллера и модели;
  • могут напрямую обращаться к свойствам и методам контроллера или моделей. Однако это должно делаться только в целях отображения данных.
Контроллеры:
  • могут обращаться к $_GET, $_POST и другим переменным PHP, получаемым из запроса пользователя;
  • могут создавать экземпляры моделей и управлять ими. К примеру, в типичном действии обновления модели контроллер может сначала создать экземпляр модели, затем заполнить его данными из $_POST и, в случае успешного сохранения модели, перенаправить браузер пользователя на страницу созданной модели. Стоит отметить, что само сохранение модели должно быть реализовано в классе модели, а не в контроллере;
  • не должны содержать SQL-запросы. Их лучше держать в моделях;
  • не должны содержать HTML и другую разметку. Её стоит вынести в представления.
(Требования позаимствованы отсюда: http://yiiframework.ru/doc/guide/ru/basics.best-practices)

Кроме концепции MVC существуют и многие другие, например MOVE ( Models, Operations, Views и Events ) — вроде, как эволюция MVC (взято отсюда: http://habrahabr.ru/post/147038/), но эти концепции менее распространенные.

Шаблон проектирования Model‑View‑Controller (MVC) на примере Lego — PYTHON

В этом уроке:

Давай пройдемся по закоулкам своей памяти и покажем как веб‑приложение по шаблону Model‑View‑Controller (или MVC), работает на практике…

Lego!

Тебе десять лет и ты сидишь на полу в семейном кругу с большой коробкой Lego. Lego есть самых разнообразных форм и размеров. Голубые, высокие и длинные. Есть тракторный прицеп. Некоторые красные и почти кубики. А некоторые желтые — большие широкие пластины, похожие на листы стекла. Со всеми этими различными Lego невозможно предсказать, что можно соорудить.

О, чудо! Уже есть запрос. Старший брат подбегает и требует: «Сделай мне космическую ракету!»

«Хорошо, — думаешь ты — космическая ракета это будет круто!».

Итак, ты приступил к работе. Ты начинаешь выискивать Lego, который нужен. Большие и маленькие. Разных цветов для космической ракеты, разных цветов для двигателей. Ух ты, это разноцветные бластеры. (Тебя обязательно нужен бластер!)

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

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


О чём вы подумаете, если я скажу, что создавать веб‑приложения точно так же просто, как собирать игрушки из Lego?

Все начинается с запроса

В случае с Lego ваш брат попросил вас что-то сделать. Аналогично с веб‑приложением пользователь, вводящий URL‑адрес, запрашивает просмотр определенной страницы.

Так что твой брат — это пользователь веба.

Запрос приходит в controler (контроллер)

С Lego ты главный, controler (контроллер).

Контролер отвечает за сбор всех необходимых строительных блоков и по мере необходимости их организацию.

Строительные блоки есть model (модель)

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

Итак, запрос пришёл…

Контролер, то есть ты, получает запрос.

Идет к моделям (Lego), чтобы получить необходимые предметы.

И теперь всё готово для производства конечного продукта.

Конечный продукт известен как view (представление)

Космическая ракета это представление. Это продукт, который в конечном итоге будет показан человеку, который сделал запрос (твоему брату).

В веб‑приложении представление — это последняя страница, которую пользователь видит в своем браузере.

Подводим итоги…

При строительстве с Lego:

  1. Твой брат просит тебя построить космический корабль.
  2. Ты принимаешь запрос.
  3. Ты находишь и организуете все Lego, которые нужны для постройки космической ракеты.
  4. Ты используешь Lego для создания космической ракеты и презентации её своему брату.
Построение web-приложения по шаблону MVC, как Лего

И в web‑приложении:

  1. Пользователь запрашивает просмотр страницы, вводя URL.
  2. Controller получает этот запрос.
  3. Он использует Models для извлечения всех необходимых данных, организует их и отправляет в…
  4. View, который затем использует эти данные для отображения окончательной веб‑страницы, презентуемой пользователю в его браузере.
Маршрутизация в MVC

Ближе к технике

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

Когда вы вводите URL в своем браузере для доступа к веб‑приложению, вы делаете запрос на просмотр определенной страницы в приложении. Но как приложение узнает, какую страницу показывать/отображать?

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

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

Маршруты

Каждый маршрут связан с контроллером, точнее, с определенной функцией внутри контроллера, известной как действие контроллера. Поэтому, когда вы вводите URL‑адрес, приложение пытается найти соответствующий маршрут и, в случае успеха, вызывает соответствующее действие контроллера для этого маршрута.

Давайте рассмотрим базовый маршрут для Flask в качестве примера:


@app route('/')
def main_page():
    pass

Здесь мы устанавливаем маршрут /, связанный с функцией представления main_page().

Модели и контроллеры

Внутри контроллера обычно происходят две основные вещи: 1) модели используются для извлечения всех необходимых данных из базы данных; и 2) эти данные передаются в представление, которое отображает запрашиваемую страницу. Данные, полученные с помощью моделей, обычно добавляются в структуру данных (например, список или словарь) и именно эта структура отправляется в представление.

Вернемся к нашему примеру с Flask:


@app.route('/')
def main_page():
    """Searches the database for entries, then displays them."""
    db = get_db()
    cur = db.execute('select * from entries order by id desc')
    entries = cur.fetchall()
    return render_template('index.html', entries=entries)

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

Views

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

Опять же, возвращаясь к нашему приложению Flask, мы можем перебирать записи, отображая каждую из них с использованием синтаксиса Jinja:


{% for entry in entries %}
  
  • {{ entry.title }}

    {{ entry.text|safe }}

  • {% else %}
  • No entries yet. Add some!
  • {% endfor %}

    Итоги

    Итак, более подробное техническое описание процесса запроса MVC выглядит следующим образом:

    1. Пользователь запрашивает просмотр страницы, вводя URL.
    2. Приложение сопоставляет URL‑адрес с предварительно определенным маршрутом.
    3. Вызывается действие контроллера, связанное с маршрутом.
    4. Действие контроллера использует модели для извлечения всех необходимых данных из базы данных, размещения данных в массиве и загрузки представления, передавая структуру данных.
    5. view осуществляет доступ к структуре данных и использует ее для отображения запрошенной страницы, которая затем представляется пользователю в их браузере..

    По мотивам: Model-View-Controller (MVC) Explained – With Lego

    Паттерны представления данных в 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. В большинстве корпоративных систем представление по шаблону должно выступать исключительно в качестве


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

    Шаблон проектирования «модель-представление-контроллер» — Блог веб-программиста

    Подробности
    октября 22, 2014
    Просмотров: 4365

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

    Этим термином обозначается архитектурная цель для поддержания отличий между тремя функциональными аспектами программы, дающими пользователю возможность просматривать и править информацию. Это означает, что программа, по существу, обладает графическим пользовательским интерфейсом. Упоминание о шаблоне МУС относится еще к временам языка Smalltalk, и на тему его применения в разработке прикладного программного обеспечения написано немало. Неформально термин шаблон проектирования “модель-представление-контроллер» обозначает следующее.

    Модель

    Описывает данные и управление ими и нередко называется также бизнес-логикой прикладной программы, т.е. самой ее сердцевиной.

    Представление

    Описывает то, что пользователь видит и с чем он может взаимодействовать в прикладной программе.

    Контроллер

    Служит в качестве посредника между моделью и представлением.

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

    • Класс UILabel, отвечающий за отображение для пользователя текущего счета по ходу игры, выполняет функции представления. По существу, он лишь воспроизводит информацию по отдельным пикселям и должен знать, как это делается. Обязанность знать, что именно следует воспроизводить (в данном случае — счет в игре), возлагается на другую составляющую рассматриваемого здесь шаблона.
    • Начинающий программист может попытаться воспользоваться счетом в игре, отображаемым средствами класса UILabel, как конкретным числом, чтобы увеличить его, прочитав его как символьную строку типа UILabel, преобразовав эту строку в число, увеличив последнее, преобразовав его обратно в символьную строку и представив ее вместо прежней строки. Однако это было бы грубым нарушением самого принципа, положенного в основу шаблона MVC. Представление, которое предоставляется пользователю, должно отражать счет в игре, но не хранить этот счет.
    • Счет — это данные, поддерживаемые внутренним образом, т.е. в модели. Модель может быть простой, как переменная экземпляра с открытым методом увеличения счета в игре, или же сложной, как объект класса Score с целым рядом методов специального назначения.
    • Счет относится к числовому типу данных, тогда как класс UILabel отображает символьную строку. Одного этого достаточно, чтобы показать, что представление и модель имеют естественные отличия.
    • В обязанности контроллера входит уведомление о моменте изменения счета и управление отображением обновленного счета в пользовательском интерфейсе. Это особенно очевидно, если представить, что числовое значение счета в игре требуется, так или иначе, преобразовать в форму, удобную для представления пользователю.
    • Допустим, что класс UILabel, представляющий счет, сообщает следующее: “Ваш текущий счет равен 20”. Предположительно, обязанность за сохранение и предоставление счета 20 пользователю возлагается на контроллер.

     

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

     

     

    Рис. 13.2. Шаблон проектирования «модель-представление-контроллер»

     

    Приверженность шаблону MVC особенно присуща приложениям Cocoa, поскольку этот шаблон поддерживается в самой среде Cocoa. Это видно из названий классов Cocoa. Например, класс UlView реализует представление, а класс UlViewController — контроллер, воплощающий логику управления отображением представления. В главе 11 было показано, что класс UlPickerView не содержит данные, которые он отображает. Он получает эти данные из источника данных. Следовательно, класс UlPickerView обозначает представление, а источник данных — модель.

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

    Например, в одном из моих приложений загружается XML-документ из ленты новостей, а заглавия статей предоставляются пользователю в виде таблицы. Сохранение и синтаксический анализ XML-файла являются исключительно материалом модели, и поэтому они повторно используются настолько часто, что я даже не пытался писать эту часть прикладного кода, а воспользовался готовым кодом под названием FeedParser, написанным Кевином Баллардом (Kevin Ballard). Представление таблицы обеспечивается классом UITableView и также является повторно используемым как получаемое непосредственно из среды Cocoa. Однако когда класс UITableView обращается к коду моего приложения и запрашивает, что именно следует отображать в данной ячейке, или когда код моего приложения обращается к XML-документу и запрашивает заглавие статьи, соответствующее данной строке таблицы, то это уже материал, а точнее, код контроллера.

    Шаблон МУС помогает найти ответы на вопросы, касающиеся тех объектов, которые должны быть видны другим объектам в приложении. Так, объект контроллера обычно должен видеть объекты модели и представления, а объекту модели или группе объектов модели обычно не требуется видеть все, что находится на пределами самой модели. Как правило, объекту представления также не требуется видеть все, что находится на пределами самого представления, но такие структурные средства, как делегирование, источник данных и пары “цель-действие”, позволяют объекту представления связываться с контроллером независимым образом.


    Похожие статьи

     

     

     

     

     

    Понимание модели-представления-контроллера

    Похоже, что, как и все остальное в разработке программного обеспечения, концепция Model-View-Controller была первоначально изобретена программистами Smalltalk.

    В частности, его изобрел один программист на Smalltalk, Трюгве Реенскауг. Трюгве ведет страницу, на которой его словами объясняется история MVC. Он приходит к этим определениям в статье, опубликованной 10 декабря 1979 г .:

    1. Модели

      Модели представляют знания.Модель может быть отдельным объектом (довольно неинтересным) или некоторой структурой объектов.

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

    2. Просмотры

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

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

    3. Контроллеры

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

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

    Модель = HTML Просмотр = CSS Контроллер = Браузер

    Этот вездесущий trifecta почти идеально представляет MVC.

    1. Модель

      HTML — это «скелет» основного контента. Текст, передающий информацию читателю.

    2. Просмотр

      CSS добавляет к содержимому визуальный стиль. Это «кожа», которую мы используем, чтобы наполнить наш скелет плотью и придать ему особый вид.Мы можем поменять местами разные скины через CSS, никоим образом не изменяя исходный контент. Они относительно, но не полностью независимы.

    3. Контроллер

      Браузер отвечает за объединение и рендеринг CSS и HTML в набор окончательных, управляемых пикселей на экране. Он собирает ввод от пользователя и направляет его в любой код JavaScript, необходимый для работы страницы. Но и здесь у нас есть гибкость: мы можем подключить другой браузер и получить сопоставимые результаты.Некоторые браузеры могут отображать его быстрее, с большей точностью или с большим количеством наворотов.

    Так что, если вы верите, что Интернет вообще был успешным — большинство признаков, которые я видел, указывают на да — тогда вы также должны признать невероятную мощь Model-View-Controller.

    Неслучайно многие из самых популярных фреймворков веб-программирования также инкапсулируют принципы MVC: Django, Ruby on Rails, CakePHP, Struts и т. Д.Он также официально проникает в ASP.NET в рамках только что зарождающегося проекта ASP.NET MVC.

    Просто взгляните на макет проекта в примере ASP.NET MVC project :

    Это почти говорит само за себя, если вы когда-либо создавали какое-либо приложение:

    1. Модель

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

    2. Просмотр

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

    3. Контроллер

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

    Как отмечает Теренс Парр, он прекрасен своей простотой:

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

    Контроллер в веб-приложении немного сложнее, потому что он состоит из двух частей. Первая часть — это веб-сервер (например, контейнер сервлетов), который сопоставляет входящие HTTP-запросы URL-адреса конкретному обработчику этого запроса. Вторая часть — это сами обработчики, которые на самом деле часто называют «контроллерами».«Итак, C в веб-приложении MVC включает в себя как« повелителя »веб-сервера, который направляет запросы обработчикам, так и логику самих этих обработчиков, которые извлекают данные из базы данных и помещают их в шаблон. Этот контроллер также получает HTTP POST запрашивает и обрабатывает их, иногда обновляя базу данных.

    Я смотрю на веб-сайт как на не что иное, как граф с ребрами с POST и GET, которые маршрутизируют страницы.

    Вот один из быстрых способов проверить, правильно ли ваше приложение разделено между ролями модели, представления и контроллера: можно ли изменить скин для вашего приложения?

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

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

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

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

    Интеграция модели, представления и контроллера в ASP.NET MVC

    • Подписывайтесь на нас