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

Из обработки запроса естественным образом выделяется слой шаблонов, на основе которых генерируется HTML. Этот слой принято называть View (представление). Кроме него, как минимум, выделяют ещё два слоя: Model (модель) и Controller (контроллер). Остальное добавляется по мере роста сложности приложения. Аббревиатура MVC (Model-View-Controller) — тема нашего урока.

Существует две разных версии MVC. Та, которая была придумана изначально (в сообществе программистов на SmallTalk), создавалась под толстые клиенты, а они представляют собой событийные системы, как современные фронтенд-приложения. На сервере используется другая вариация MVC, которая называется MVC v2. Буквы в ней те же, но означают местами другое, и самое главное, что совсем по-другому строится взаимодействие.

MVC

Архитектурный шаблон MVC задаёт основную структуру приложения и позволяет коду достаточно долго развиваться, оставаясь удобным в поддержке. MVC, с некоторыми модификациями, реализуется всеми веб-фреймворками. И если с представлением всё понятно, то с моделью и контроллером нужно разбираться отдельно. Под контроллерами понимаются обработчики запросов. Они принимают объект запроса и возвращают объект ответа. В случае Slim, контроллеры представлены анонимными функциями, но это не обязательно: в больших фреймворках контроллер — это класс, а обработчики — его методы. Эти методы обычно именуют действиями (actions). В принципе, на этом наше разделение можно было бы и закончить. При таком подходе вся логика сосредоточена в самих контроллерах, что вполне допустимо в самых примитивных случаях.

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

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

Зачем понадобилось выделять слой модель? Достаточно давно мне попалась на глаза интересная статья, которая называлась Rails is not your application (Rails — популярный веб-фреймворк, который стал прообразом для большинства современных фреймворков на разных языках программирования). Идея статьи заключается в том, что предметная область, которую мы реализуем внутри нашего сайта, никак не связана ни с сайтом ни тем более с фреймворком, который используется внутри. Посудите сами, могут ли поменяться правила бухгалтерии в зависимости от выбранного фреймворка и вообще, как связана бухгалтерия и фреймворк? Очевидно, никак и бизнес-правила этой области не зависят от существования программирования. Посредством программирования мы можем их выразить в коде, но этот код снова не будет связан с используемым фреймворком. В идеале, код который описывает предметную область и позволяет с ней работать, можно взять и перенести в другой фреймворк без модификаций. Как видно, на логическом уровне есть граница между кодом, моделирующим предметную область, и кодом, обслуживающим веб-запросы. Но эту границу иногда провести трудно. Например, к чему относится отправка письма при регистрации, а авторизация, а восстановление пароля? Если закапываться дальше, то на горизонте возникают понятия Application Logic и Business Logic, а затем и Service Layer. Если вам интересно, то прочитайте про них самостоятельно.

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

MVC
Relations

Взаимоотношения между слоями в MVC не менее важны, чем наличие самих слоёв. Модель, как мы уже выяснили, живёт своей жизнью и не знает (и не может знать) ничего про существование контроллера или представления. Последние, в свою очередь, используют модель для запуска бизнес-логики или для формирования HTTP-ответа. Контроллер инициирует различные процессы и запуск бизнес-логики. Кроме того, контроллер отвечает за формирование ответа и запускает рендеринг шаблонов. Шаблоны не знают про существование слоя контроллера, но используют данные, предоставленные им для формирование HTML (или JSON, или чего-то ещё).

Мы учим программированию с нуля до стажировки и работы. Попробуйте наш бесплатный курс «Введение в программирование» или полные программы обучения по Node, PHP, Python и Java.

Хекслет

Подробнее о том, почему наше обучение работает →