Содержание
  1. Расшифровка MVC и роли трёх компонентов
  2. Полный псевдокод: запрос карточки ремонта
  3. Эталон 200 и 404: три проверки границ
  4. Терминология Django: view, template и controller
  5. Как читать этот разбор и где чаще всего ошибаются
  6. Частые вопросы
Справочник

MVC: что это и как работает в веб-разработке

5 ноября 2026 · 8 минут чтения

MVC (Model-View-Controller) — архитектурный шаблон, который делит приложение на три группы компонентов: модель, представление и контроллер. MDN описывает его как способ разделить бизнес-логику и отображение, чтобы упростить поддержку кода. Модель управляет данными и правилами, представление отвечает за вывод, контроллер направляет команды между ними.

Расшифровка MVC и роли трёх компонентов

Аббревиатура MVC раскрывается как Model, View, Controller. Это три группы ответственности. Microsoft в обзоре ASP.NET Core MVC пишет, что шаблон разделяет приложение на модели, представления и контроллеры и помогает достичь разделения ответственности. Пользовательский запрос попадает в контроллер, тот работает с моделью, выбирает представление и передаёт ему нужные данные.

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

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

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

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

Компонент Что делает Чего в нём нет
Модель Правила предметной области, состояние Разметки и разбора URL
Представление Показ готовых данных Запросов к базе
Контроллер Разбор запроса, выбор модели и представления Придуманных цен и SQL
Репозиторий Параметризованные запросы к хранилищу Бизнес-правил

Таблица показывает границу: разбор пути и HTTP-статуса живёт в контроллере, доменные правила — в модели, параметризованный SQL — в репозитории под моделью, готовые данные, экранирование и подписи — в представлении.

Полный псевдокод: запрос карточки ремонта

Разберём учебный пример. Это framework-neutral псевдокод. Вход: GET /repairs/41, запись {id:41, item:"чайник", status:"ready", price:800}. Договор отображения: статус ready превращается в «готово», метка валюты выбрана «руб.». Пример описывает логику.

ТЕКСТ17 строк
Repository.find(id):
    выбрать строку repairs по параметру :id
    вернуть запись или None
RepairService.get(id):
    row = Repository.find(id)
    если row is None: вернуть None
    проверить доменные поля row
    вернуть Repair(row.id, row.item, row.status, row.price)
Controller.detail(path_id):
    id = parse_integer(path_id)
    record = RepairService.get(id)
    если record is None: вернуть HTTP(404, "Ремонт не найден")
    вернуть HTTP(200, View.card(record))
View.card(record):
    labels = {"ready": "готово"}
    вернуть "Ремонт " + escape(record.id) + ": " + escape(record.item)
        + ", " + escape(labels[record.status]) + ", " + escape(record.price) + " руб."

Здесь escape обозначает HTML-экранирование в выбранном шаблонизаторе. Порядок вызовов задаёт маршрут запроса: контроллер разбирает путь, сервис достаёт запись через репозиторий, представление собирает строку. Каждый слой знает только свою часть работы.

Эталон для записи 41: HTTP 200, текст «Ремонт 41: чайник, готово, 800 руб.». Представление переводит статус по словарю подписей и подставляет цену из записи. Контроллер не вычисляет цену и не знает про словарь подписей — он передаёт запись дальше.

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

Эталон 200 и 404: три проверки границ

Для несуществующего идентификатора 42 сервис возвращает None, контроллер формирует HTTP 404 без вызова View.card. Представление не запускается, потому что показывать нечего. Это и есть граница: отсутствие данных обрабатывается до отрисовки.

Три проверки, которые показывают, что ответственности разошлись правильно.

Проверка 1. Запись 41 отображает именно переведённый статус и цену 800. Если в ответе появилось «ready» вместо «готово», значит перевод статуса уехал не в тот слой. Подпись живёт в представлении, и её место там.

Проверка 2. Запись 42 не вызывает View.card и даёт 404. Если представление всё-таки вызвалось, значит контроллер не проверил результат сервиса. Проверка на None стоит до выбора представления.

Проверка 3. В представлении нет SQL, а контроллер не придумывает цену. Если в шаблоне появился запрос к базе, доступ к данным просочился в отображение. Если контроллер сам считает стоимость, бизнес-правило уехало из модели.

Ситуация Ответ Что вызвано
GET /repairs/41 HTTP 200 View.card с записью
GET /repairs/42 HTTP 404 Ответ без View.card
Статус ready «готово» Словарь подписей в представлении
Цена 800 800 руб. Значение из записи

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

Терминология Django: view, template и controller

Названия компонентов в разных фреймворках расходятся. Официальный FAQ Django объясняет, почему проект использует свою схему. Django называет свою раскладку MTV — model, template, view.

В трактовке Django представление (view) определяет, какие данные нужно показать пользователю. Представление — это Python-функция-обработчик для конкретного URL, потому что она определяет, какие данные подаются. Отделение содержания от подачи выполняет template: view описывает, какие данные представить, а template — как их показать.

Где же контроллер? FAQ Django относит роль controller скорее к самому фреймворку: это machinery, которая по конфигурации URL отправляет запрос нужному view. Обычная Django view не объявляется однозначным классическим MVC-контроллером. Поэтому раскладка нашего псевдокода не переносится механически на названия Django: то, что в примере называется контроллером, в терминах Django ближе к URL-механике и выбору view.

Термин В нашем примере В терминологии Django
Model Правила и состояние Model
View (данные) Контроллер выбирает данные View — какие данные
View (показ) Представление Template — как показать
Controller Разбор запроса Framework и URL machinery

Microsoft и MDN дают свои примеры и своё разделение ролей. MDN описывает модель как управление данными и логикой, представление как разметку и показ, контроллер как маршрутизацию команд. В обзоре Microsoft контроллер — точка входа, которая выбирает модель и представление. Rails в руководстве для начинающих показывает собственный пример разделения. Один шаблон, разные имена.

Как читать этот разбор и где чаще всего ошибаются

Проверку удобно вести от ожидаемого ответа к коду. Сначала зафиксируйте, что должно получиться для записи 41: код 200 и строка с переведённым статусом и ценой. Затем пройдите маршрут по шагам и на каждом спросите, кто отвечает за этот шаг. Если ответ «никто конкретный» или «сразу двое», граница размыта.

Типичная ошибка новичка — перенести перевод статуса в контроллер или в сервис. Внешне ответ совпадёт, но при добавлении нового статуса правки расползутся по нескольким файлам, а представление начнёт зависеть от доменных значений. Вторая частая ошибка — проверять существование записи уже внутри представления. Тогда для идентификатора 42 отрисовка всё равно запустится, и вместо чистого 404 появится пустая или сломанная карточка.

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

Частые вопросы

MVC что это простыми словами?
Это способ разложить приложение на три части: правила работы с данными, показ результата и обработку запроса. MDN описывает шаблон как разделение бизнес-логики и отображения. Каждая часть получает одну задачу, поэтому код проще менять и тестировать.

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

Чем контроллер отличается от представления?
Контроллер разбирает запрос, вызывает модель и выбирает, что показать. Представление получает готовые данные и строит разметку. Microsoft пишет, что представление только показывает информацию, а контроллер обрабатывает ввод и взаимодействие. В нашем примере контроллер формирует HTTP-статус, представление собирает строку карточки.

Почему в Django view называется не так, как в MVC?
Django использует схему MTV: model, template, view. В трактовке Django view описывает, какие данные представить, а template — как их показать. Роль controller FAQ Django относит скорее к самому фреймворку и URL-механике, выбирающей view. Поэтому имена расходятся, хотя идея разделения сохраняется.

Как проверить, что слои MVC не смешались?
Возьмите два запроса: существующий и несуществующий идентификатор. Существующий должен вернуть 200 с переведённым статусом и ценой из записи, несуществующий — 404 без вызова представления. Затем проверьте, что в представлении нет SQL, а контроллер не вычисляет бизнес-значения. Эти три проверки показывают границы ответственности.

Читайте также

3 материала