MVC для веб: проще некуда
В этой статье мы рассмотрим архитектурный паттерн MVC (Model, View, Controller) в применении к веб-разработке, «в чистом виде», без привлечения каких-то дополнительных, не относящихся к MVC структур и паттернов. Мы будем продвигаться от простого к сложному, поэтому пока не станем рассматривать, например, дальнейшее развитие MVC – паттерн HMVC (Hierarchical MVC). Хотя HMVC, несомненно, намного более интересен для разработки веб-приложений, но его применение не отменяет необходимости понимания «обычного» MVC.
Статья в Википедии (а именно туда, видимо, чаще всего попадают те, кто только начинает изучать MVC), изобилует неточностями и туманными формулировками, само определение, по сути, является неверным, а приведенная схема просто напросто не соответствует той, которая применяется в веб вообще и при разработке на PHP – в особенности.
Наиболее корректное определение паттерна MVC я обнаружил тут:
Шаблон проектирования MVC предполагает разделение данных приложения, пользовательского интерфейса и управляющей логики на три отдельных компонента: Модель, Представление и Контроллер – таким образом, что модификация каждого компонента может осуществляться независимо.
Уточним, что термин «компонент» в данном случае не имеет никакой связи с компонентами некоторых популярных CMS или фреймворков, а компоненты Битрикса, например вообще строятся из всех трёх составляющих MVC.
В приведённом определении под компонентом следует понимать некую отдельную часть кода, каждая из которых играет одну из ролей Контроллера, Модели или Представления, где Модель служит для извлечения и манипуляций данными приложения, Представление отвечает за видимое пользователю отображение этих данных (то есть, в применении к вебу, формирует отдаваемый сервером браузеру пользователя HTML/CSS), а Контроллер управляет всем этим оркестром.
Давайте рассмотрим классическую схему веб-приложения:
Рисунок 1

На этом и последующем рисунках пунктирными линиями показана управляющая информация (такая, например, как ID запрашиваемой записи блога или товара в магазине), а сплошными – собственно данные приложения (которые могут храниться в БД, или в виде файлов на диске, или даже, возможно, в оперативной памяти – этот вопрос лежит за пределами паттерна MVC). В применении к вебу запрос и ответ ходят по HTTP, поэтому можно условно считать, что на этом рисунке пунктиром обозначены заголовки HTTP-запроса и ответа, а сплошными линиями – их тела.
Получив Запрос 1, Контроллер его анализирует, и в зависимости от результатов обработки может выдать следующие варианты ответа (почему ответ имеет номер 4, станет понятно из следующих рисунков):
1. Сразу выдать ответ об ошибке (например, при запросе несуществующей страницы отдать только HTTP-заголовок «404 Not found»)
2. Если поступивший Запрос 1 признан корректным, то, в зависимости от того, является он запросом на просмотр или на модификацию данных, Контроллер вызывает соответствующий метод Модели, такой как Save или Load (Запрос 2 на Рис.2).
Рисунок 2

Важное замечание: концепция MVC не только не привязана к какому-то конкретному языку программирования, она также не привязана и к используемой парадигме программирования. То есть, вы вполне можете проектировать своё приложение по MVC, при этом не применяя ООП, и спроектировать Модель Товар для интернет-магазина таким образом:
// возвращает ассоциативный массив с данными о Товаре либо FALSE при неудаче bool Product_Save (array $data) < . >// возвращает TRUE при удачном сохранении данных $data, либо FALSE при неудаче ?>
Итак, в зависимости от полученного от Модели Ответа 2 Контроллер решает, какое из Представлений вызвать для формирования итогового ответа на изначальный Запрос 1:
3.1. В случае неудачи – Представление для сообщения об ошибке
3.2. В случае успеха – Представление для отображения запрашиваемых данных либо сообщения об их успешном сохранении (если Запрос 1 был на изменение данных).
Рисунок 3

Вопрос о том, кто должен проверять на валидность и права доступа входные данные (Контроллер или Модель), является предметом достаточно многочисленных споров, поскольку паттерн MVC не описывает таких деталей. Это значит, что в этом вопросе выбор за вами (или за вас его сделали авторы вашего любимого фрейvворка или CMS).
Мы в своей практике придерживаемся такого подхода:
Контроллер проверяет входные данные на предмет «общей» (т.е. независящей от конкретного запроса) корректности, соответствие требованиям Модели к валидности сохраняемых данных проверяет соответствующий метод Модели, а права доступа – метод Access отдельного класса User.
Для вызова Представления в PHP иногда проектируется специальный класс (а то и несколько классов), например, View (это часто встречается в описаниях MVC в реализации того или иного фреймворка), однако это не является требованием MVC.
Также файлы Представлений часто называют шаблонами, а при использовании так называемых шаблонизаторов роль Представления играет сам шаблонизатор, а шаблоны (т.е. файлы, содержащие непосредственно HTML-разметку) в некоторых фреймворках называют layouts.
Не вполне понятен предыдущий абзац? Забейте, поскольку у нас каждое Представление – это просто отдельный PHP-файл, а сам PHP устроен так, что в случае, если мы используем для выполнения Запроса 3 инструкцию include, Ответ 3 и Ответ 4 (помните, что это ответ на Запрос 1?) отдаются браузеру автоматически, средствами самого PHP.
Давайте рассмотрим пример.
У нас есть два варианта Представления (шаблоны), в которых
будет означать HTML-код, предворяющий в формируемом веб-документе основной контент (т.е. содержит тег doctype, контейнер head, код шапки страницы, и т.п.), а – примерно то же, только для подвала страницы.
Листинг 1. Шаблон product.tpl.php отображает данные о Товаре (которые к моменту его вызова уже содержит объект $product):
Title;?>
Цена:Price;?>
Description;?>
Листинг 2. Шаблон error.tpl.php отображает сообщение об ошибке (которое содержится в переменной $error):
Ошибка:
Листинг 3. Контроллер product.php, служащий для отобоажения Товара, будет выглядеть примерно так:
if (!$id = . ) // проверка "общей" валидности Запроса 1 error(. ); // проверка прав доступа if (!$user->Access(. )) error(403); if (!$product = Product::Load($id)) // Запрос 2 и анализ Ответа 2 error('Тут скорее всего случилась ошибка БД'); include 'product.tpl.php'; // Запрос 3 и Ответы 3 и 4 ?>
Те, кто любит красивый и оптимизированный код могут заметить, что блоки HTML.header и HTML.footer дублируются в обоих шаблонах (они же Представления) error.tpl.php и product.tpl.php, и наверняка захотят вынести их в Контроллер product.save.php:
…. и нарушить таким образом основное правило MVC – разделяйте Контроллер, Модель и Представление.
Тем не менее, дублирующийся код – однозначное Зло. Что же делать?
Мы должны перейти от MVC к HMVC!
Но это – тема отдельной статьи.
Что такое MVC: рассказываем простыми словами

Современные сайты интерактивные и динамичные — они реагируют на действия пользователя, обрабатывают его запросы и выдают результат. Так работают многие онлайн-сервисы, например, интернет-банкинги или онлайн-кинотеатры. Для создания интерактивных и динамичных сайтов обычно используется архитектурный паттерн MVC. Рассказываем простыми словами, в чем суть этой модели.
- Что такое модель MVC: теория
- Разбираем MVC на примере магазина сэндвичей
- Паттерн MVC в реальной веб-разработке: как работает контроллер
- Модель
- Представление
- Заключение
Что такое модель MVC: теория
Статическая страница на HTML не умеет реагировать на действия пользователя. Для двухстороннего взаимодействия нужны динамические веб-страницы. MVC — ключ к пониманию разработки динамических веб-приложений, поэтому разработчику нужно знать эту модель.
MVC расшифровывается как «модель-представление-контроллер» (от англ. model-view-controller). Это способ организации кода, который предполагает выделение блоков, отвечающих за решение разных задач. Один блок отвечает за данные приложения, другой отвечает за внешний вид, а третий контролирует работу приложения.
Fullstack-разработчик — с нуля до трудоустройства за 16 месяцев
- Постоянная поддержка от наставника и учебного центра
- Помощь с трудоустройством
- Готовое портфолио к концу обучения
- Практика с первого урока
Вы получите именно те инструменты и навыки, которые позволят вам найти работу
- Модель — этот компонент отвечает за данные, а также определяет структуру приложения. Например, если вы создаете To-Do приложение, код компонента model будет определять список задач и отдельные задачи.
- Представление — этот компонент отвечает за взаимодействие с пользователем. То есть код компонента view определяет внешний вид приложения и способы его использования.
- Контроллер — этот компонент отвечает за связь между model и view . Код компонента controller определяет, как сайт реагирует на действия пользователя. По сути, это мозг MVC-приложения.
Разбираем MVC на примере магазина сэндвичей
Мы уже рассматривали работу с вложенными коллбэками на примере приготовления гамбургеров. Продолжаем традицию: разберем паттерн MVC на примере магазина сэндвичей.
Представьте, что вы пришли в магазин или кафе, где можно заказать сэндвич. В меню есть бутерброды с тунцом, индейкой и ветчиной. Вы заказываете сэндвич с индейкой. Продавец понимает вас с полуслова. Он поворачивается в сторону кухни и говорит поварам, чтобы они приготовили сэндвич с индейкой.
У поваров под рукой есть разные продукты: тунец, индейка, ветчина, сыр, листья салата и другие ингредиенты, которые добавляют в бутерброды. Они выбирают только то, что нужно для вашего сэндвича с индейкой. Вы получаете свой заказ.
Покупку бутерброда можно описать через MVC:
- Модель: кухня, на которой повар делает сэндвич
- Представление: готовый бутерброд, который вы с удовольствием едите
- Контроллер: продавец или бармен, который принимает заказ и передаёт его на кухню.

Вы уже представляли готовый сэндвич с индейкой, когда заказывали его бармену. Это представление или view .
Точно так же можно представить взаимодействие с сайтом. Когда вы заходите на сайт Хекслета и переходите по ссылке «Истории успеха», то заранее представляете результат перехода по ссылке. Это список текстов с историями ребят, которые учились на Хекслете, а потом стали разработчиками.
Когда вы нажимаете на ссылку «Истории успеха», на наш сервер уходит запрос. В нём содержится просьба показать вам список текстов. Это очень похоже на просьбу продать вам бутерброд с индейкой. Это контроллер.
На сервере Хекслета ваш запрос обрабатывается. Программа достаёт из базы данных все последние тексты из рубрики «Истории успеха», чтобы показать список. Это можно сравнить с кухней и поварами из примера с сэндвичем. Это модель.
Сервер Хекслета берёт нужные ингредиенты из базы данных и готовит ваш заказ: список текстов. Тем же занимались повара на кухне магазина сэндвичей. Это снова представление или view .
Паттерн MVC в реальной веб-разработке: как работает контроллер
Контроллер обрабатывает входящие запросы. Во фреймворке это может заключаться в определении конкретных URL, на которые попадает пользователь при переходе по ссылке или при нажатии кнопки. Рассмотрим это на примере сайта, который отдает пользователю список его друзей:
возвращает profilewebsite(.)com/friends/ -> возвращает friendswebsite(.)com/friend=/ -> возвращает профиль конкретного друга
Модель
Модель отвечает за данные, которые хранятся и обрабатываются на сервере.
, friends >
Представление
Это HTML-шаблон, который возвращает сервер после обработки запроса. Если запрос корректно обрабатывается, вы получаете веб-страницу со списком друзей. Если запрос некорректный, вы попадаете на страницу ошибки 404.
Заключение
MVC — подход к проектированию приложения, который предполагает выделение кода в блоки типов модель, представление и контроллер. Контроллер обрабатывает входящие запросы. Модель достаёт из базы данных информацию, нужную для выполнения конкретных запросов. Представление определяет результат запроса, который получает пользователь.
Профессия «Fullstack-разработчик»
- Станьте специалистом полного цикла и создавайте веб-приложения с нуля
- Научитесь верстать страницы в HTML и CSS
- Изучите фронтенд-разработку на JavaScript
- Освойте платформу Node.JS и соберите весь бэкенд с ее помощью
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.
Статья опубликована в 2019 году
Тематические статьи
SOLID — принципы объектно‑ориентированного программирования
SOLID это аббревиатура пяти основных принципов проектирования в объектно‑ориентированном программировании, предложенных Робертом Мартином:
- Single responsibility — принцип единственной ответственности
- Open-closed — принцип открытости / закрытости
- Liskov substitution — принцип подстановки Барбары Лисков
- Interface segregation — принцип разделения интерфейса
- Dependency inversion — принцип инверсии зависимостей
веб-разработка
методологии разработки
Статья опубликована в 2019 и обновлена в 2023 году
REST и RESTful — передача репрезентативного состояния и ресурсный роутинг
REST — это стиль построения архитектуры распределенного клиент‑серверного приложения, который упрощает роутинг и построение API.
методологии разработки
веб-разработка
Статья опубликована в 2014 году
Стандарты кодирования — залог хорошей сопровождаемости проекта
Любая командная разработка может быть эффективной только в том случае, если участники команды имеют общее видение.
Если над проектом работает команда, а не один‑два разработчика, то обязательно должен быть стандарт оформления кода — набор правил и соглашений, которые описывают базовые принципы оформления программного кода, используемого совместно группой разработчиков.
методологии разработки
веб-разработка
Статья опубликована в 2014 и обновлена в 2023 году
Принцип программирования YAGNI — «Вам это не понадобится»
Принцип заключается в том, что возможности, которые не описаны в требованиях к системе, просто не должны реализовываться.
В результате разработка ненужных функций не сжигает бюджет проекта, а разработчики не тратят оплачиваемое время на реализацию и дальнейшее сопровождение в реальности ненужного функционала. Избыточный функционал сжигает больше всего ресурсов именно на сопровождении: больше написанного кода — труднее сопровождать и выше вероятность появления «багов». И тут очень уместна поговорка: «лучший код — это ненаписанный код».
методологии разработки
веб-разработка
Статья опубликована в 2019 и обновлена в 2023 году
Принцип программирования KISS — делайте вещи проще
KISS — это принцип проектирования и программирования, при котором простота системы декларируется в качестве основной цели или ценности.
Большая часть программных систем необосновано перегружена практически ненужными функциями, что ухудшает удобство их использование конечными пользователями, а также усложняет их поддержку и развитие разработчиками. Следование принципу KISS позволяет разрабатывать решения, которые не обладают этими недостатками: они просты в использовании и в сопровождении.
методологии разработки
веб-разработка
Статья опубликована в 2019 и обновлена в 2023 году
Принцип программирования DRY — don’t repeat yourself / не повторяйте себя
Следование принципу DRY позволяет добиться высокой сопровождаемости программного продукта: внесение изменений и тестирование значительно упрощаются.
Если код не дублируется, то для изменения логики достаточно внесения исправлений всего в одном месте. Также значительно проще тестировать одну (пусть и более сложную) функцию, а не набор из десятков однотипных. При следовании DRY упрощается и повторное использование функций, вынесенных из сложных алгоритмов, что позволяет сократить время разработки и тестирования новой функциональности.
веб-разработка
методологии разработки
Статья опубликована в 2018 и обновлена в 2023 году
TDD — разработка через тестирование
TDD, test-driven development или разработка через тестирование — это методология разработки ПО, повышающая надёжность и сопровождаемость проектов.
TDD основывается на повторении коротких циклов разработки: сначала пишется тест, покрывающий желаемое изменение, затем пишется программный код, который реализует желаемое поведение системы и позволяет пройти написанный тест, а после этого проводится рефакторинг написанного кода с постоянной проверкой прохождения тестов.
автоматизированное тестирование
тестирование
методологии разработки
Статья опубликована в 2014 и обновлена в 2023 году
Флаги функций (Feature Flags)
Флаги функций позволяют отделить развертывание функций от развертывания кода, обеспечивают возможности для A/B-тестирования и предоставляют механизм быстрого отключения проблемных функций
Что такое MVC
Каждый компонент кода выполняет свою независимую функцию:
- Модель отвечает за хранение и обработку данных программы.
- Представление определяет внешний вид приложения и обеспечивает пользовательское взаимодействие.
- Контроллер управляет логикой приложения и контролирует взаимодействие между двумя другими частями MVC (Model View Controller).
Как работает MVC
Модель определяет структуру базы данных и обрабатывает все операции, связанные с данными. Благодаря представлению, пользователь может взаимодействовать с приложением. А контроллер является посредником между ними. Это означает, что контроллер обрабатывает запросы пользователя и определяет, какие данные должны быть переданы из модели в представление.
Разберем на примере:

- Вы находитесь в магазине обуви, и вам нужны черные кроссовки.
- Модель — это склад с обувью всех размеров и видов.
- Представление — это черные кроссовки нужного вам размера.
- Контролер — это продавец, который принимает ваш заказ и передает его на склад.
Зачем программистам нужен MVC
MVC (Model View Controller) позволяет логически разбить основные функции приложения на отдельные, четко определенные компоненты, что улучшает организацию работы с кодом. Такой подход дает легкость в разработке и поддержке программного продукта. Разделение приложения на компоненты позволяет вносить изменения в один компонент, не затрагивая остальные — это упрощает обслуживание и снижает вероятность ошибок.
Представим, что вы делаете приложение, которое позволит пользователям создавать задачи и организовывать их в списки. Модель определит, что такое «задача» и что такое «список». Представление определит, как они выглядят на экране и как с ними взаимодействовать. А контроллер определит, как добавлять новые задачи или отмечать выполненные.
- Сделать ваш код более читабельным и понятным
- Разделить логику приложения и его представление
- Упростить тестирование и отладку
- Повысить гибкость и расширяемость
- Соблюдать принцип единственной ответственности (SOLID).
Где используется MVC
MVC — это общий шаблон проектирования, который существует во многих фреймворках для веб-приложений, таких как Ruby on Rails, Django и Zend Framework.
Например, фреймворк ASP.NET MVC помогает разработчикам создавать веб-приложения с помощью языков программирования C#, Visual Basic .NET.

- Позволяет создавать динамичные веб-сайты с использованием MVC паттерна (MVC Pattern).
- Обеспечивает чистое разделение интересов(Separation of Concerns), которое позволяет разработчикам изменять каждый компонент независимо друг от друга, что упрощает поддержку и расширение приложения. Например, если требуется изменить способ отображения данных пользователю, при помощи MVC можно поменять только соответствующее представление, не затрагивая остальные компоненты.
- Ускоряет разработку, благодаря использованию шаблонов проектирования.
- Не использует состояние представления или серверные формы, что делает фреймворк MVC идеальным для разработчиков, которые хотят полного контроля над поведением приложения;
- Поддерживает тестирование на основе разработки (TDD), из-за этого разработчики могут создавать приложение с модульными тестами и писать свои собственные тестовые случаи.
Книги для развития Soft Skills

7 янв. 2024 г.
Топ 11 книг как стать эффективнее

4 янв. 2024 г.