Модель-Представление-Контроллер (MVC)
Yii использует шаблон проектирования Модель-Представление-Контроллер (MVC, Model-View-Controller), который широко применяется в веб-программировании.
MVC предназначен для разделения бизнес-логики и пользовательского интерфейса, чтобы разработчики могли легко изменять отдельные части приложения, не затрагивая другие. В архитектуре MVC модель предоставляет данные и правила бизнес-логики, представление отвечает за пользовательский интерфейс (например, текст, поля ввода), а контроллер обеспечивает взаимодействие между моделью и представлением.
Помимо этого, Yii использует фронт-контроллер, называемый приложением (application), который инкапсулирует контекст обработки запроса. Приложение собирает информацию о запросе и передает её для дальнейшей обработки соответствующему контроллеру.
Следующая диаграмма отображает структуру приложения Yii:
Статическая структура приложения Yii
1. Типичная последовательность работы приложения Yii ¶
Следующая диаграмма описывает типичную последовательность процесса обработки пользовательского запроса приложением:
Типичная последовательность работы приложения Yii
- Пользователь осуществляет запрос посредством URL http://www.example.com/index.php?r=post/show&id=1 , и веб-сервер обрабатывает его, запуская скрипт инициализации index.php .
- Скрипт инициализации создает экземпляр приложения и запускает его на выполнение.
- Приложение получает подробную информацию о запросе пользователя от компонента приложения request .
- Приложение определяет запрошенные контроллер и действие при помощи компонента urlManager . В данном примере контроллером будет post , относящийся к классу PostController , а действием — show , суть которого определяется контроллером.
- Приложение создаёт экземпляр запрашиваемого контроллера для дальнейшей обработки запроса пользователя. Контроллер определяет соответствие действия show методу actionShow в классе контроллера. Далее создаются и применяются фильтры (например, access control, benchmarking), связанные с данным действием, и, если фильтры позволяют, действие выполняется.
- Действие считывает из базы данных модель Post с ID равным 1 .
- Действие подключает представление show , передавая в него модель Post .
- Представление получает и отображает атрибуты модели Post .
- Представление подключает некоторые виджеты.
- Сформированное представление вставляется в макет страницы.
- Действие завершает формирование представления и выводит результат пользователю.
Found a typo or you think this page needs improvement?
Edit it on github !
Что такое MVC: базовые концепции и пример приложения
Объясняем, что такое паттерн MVC и как он помогает упростить разработку.
Евгений Кучерявый
Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.
MVC — это шаблон программирования, который позволяет разделить логику приложения на три части:
- Model (модель). Получает данные от контроллера, выполняет необходимые операции и передаёт их в вид.
- View (вид или представление). Получает данные от модели и выводит их для пользователя.
- Controller (контроллер). Обрабатывает действия пользователя, проверяет полученные данные и передаёт их модели.
Может показаться, что это что-то запутанное, но на самом деле всё просто.
Как работает MVC
Лучше всего понять концепцию MVC можно на реальном примере — ресторане с фастфудом. В нём посетители (пользователи) подходят к кассиру (одновременно вид и контроллер), видят меню и заказывают какое-нибудь блюдо.
Кассир проверяет, всё ли в порядке с заказом, и после оплаты передаёт нужные данные повару (модель). Повар готовит заказанное блюдо, хотя понятия не имеет о том, как выглядит посетитель, оплатил ли он заказ и так далее.
Когда модель закончит свою работу, она отправит результат в вид — обратно кассиру, который, в свою очередь, отдаст готовое блюдо посетителю.
Если же говорить о приложениях, то компоненты будут следующие:
- Вид — интерфейс.
- Контроллер — обработчик событий, инициируемых пользователем (нажатие на кнопку, переход по ссылке, отправка формы).
- Модель — метод, который запускается обработчиком и выполняет все основные операции (получение записей из базы данных, проведение вычислений).
Стоит также отметить, что реализация паттерна MVC может отличаться в зависимости от задачи. Например, в веб-разработке модель и вид взаимодействуют друг с другом через контроллер (как в примере с рестораном), а в приложениях модель может сама уведомлять вид, что нужно что-то изменить.
Зачем программистам нужен MVC
Этот паттерн разработки нужен для того, чтобы разделить логические части приложения и создавать их отдельно друг от друга. То есть писать независимые блоки кода, которые можно как угодно менять, не затрагивая другие.
Например, чтобы можно было переписать способ обработки данных, не меняя при этом способ их отображения. Это позволяет эффективно работать нескольким программистам — каждый занимается своим компонентом. При этом разработчику не нужно вникать в чужой код и его действия никак не повлияют на другие фрагменты приложения.
Независимым программистам MVC тоже будет полезен, потому что они смогут сосредоточиться на разработке одного компонента за раз.
Практика: пишем
MVC-приложение
Чтобы лучше вникнуть в этот паттерн, стоит применить его на практике. Для этого создайте WPF-приложение и сверстайте такую форму:
Заключение
На первый взгляд MVC может показаться сложным, но чем больше усилий уделять на его изучение, тем понятнее будет, почему многие разработчики предпочитают именно его. Особенно если сравнивать его с обычной разработкой, где за всё отвечают обработчики событий.
Читайте также:
- Как работает .NET и зачем он нужен
- GNU Emacs: как текстовый редактор из 1980-х учит программистов ценить свободное ПО
- Перечисления в C#: как правильно использовать enum
Что такое архитектура MVC: Model-View-Controller
Model-View-Controller — популярный шаблон программирования, где логика приложения делится на три различных компонента.
В этой статье расскажем о роли компонентов архитектуры MVC, начнем с короткой истории, а далее покажем, как её можно использовать в приложении.
История паттерна Model View Controller
Модель MVC была впервые представлена в 1979 году учёным Трюгве Миккьелем Хейердалом Реенскаугом. Он хотел придумать решение, как разбить сложное пользовательское приложение на более мелкие управляемые компоненты.
Шаблон MVC был впервые использован в языке программирования Small Talk. Изначально шаблоне хотели назвать «Model-View-Editor», но затем оно было изменено на «Model-View-Controller».
В 1980-х и начале 90-х годов шаблон MVC использовался главным образом в настольных приложениях. Но к концу 1990-х годов она стала довольно популярной в разработке веб-приложений. В современных веб-приложениях шаблон MVC является популярным архитектурным дизайном для организации кода.
Ниже приведен список нескольких популярных веб-фреймворков, использующих шаблон MVC:
- Ruby on Rails
- ASP.NET MVC
- Laravel
- Angular
Какие три компонента включает в себя MVC?
Шаблон программирования MVC состоит их трёх следующих компонентов:
- Model – отвечает за логику данных, лежащую в основе приложения
- View – это видимая часть приложения, то с чем взаимодействует пользователь
- Controller – работает как мозг приложения и обеспечивает связь между моделью и видом
Как шаблон MVC работает в веб-приложении?
Чтобы лучше понять, как работает шаблон MVC, лучше всего показать его в демонстрационном приложении.
Это приложение стека MERN (MongoDB, Express, React, Node) своего рода помощник менеджера офиса и отображает таблицу недавно нанятых тренеров средней школы.
Он также показывает, какие тренеры не сдали тесты на туберкулез, не прошли вакцинацию от Covid, не заполнили резюме и не прошли проверку.
Менеджер может отправлять напоминания по электронной почте тем тренерам, у которых отсутствуют документы.
Компонент Model
Модель отвечает за логику данных нашего приложения. Мы используем MongoDB для базы данных тренеров.
Для начала определяем свойства, которые будут применены к каждому тренеру в базе данных. У каждого тренера есть свойства name , email , program , application , backgroundCheck , tbTest и covidTest .
const coachSchema = new Schema(< name: < type: String, trim: true, maxLength: 32, required: true >, email: < type: String, trim: true, maxLength: 32, required: true, unique: true >, program: < type: String, trim: true, maxLength: 32, required: true >, application: < type: Boolean, required: true >, backgroundCheck: < type: Boolean, required: true >, tbTest: < type: Boolean, required: true >, covidTest: < type: Boolean, required: true >>, < timestamps: true >)
type: Boolean представляет значение true или false для свойств приложения, backgroundCheck , tbTest и covidTest .
Если у тренера одно из этих четырех свойств, помечены как false , это означает, что они не завершили процесс найма.
Создаем семь записей для нашей базы данных тренеров, и эта информация хранится в MongoDB Atlas.
Ниже приведен пример одной из записей базы данных.
Компонент «контроллер»» будет взаимодействовать с базой данных и получать необходимую информацию для отправки компоненту представление.
Компонент View
Компонент View (вид, представление или вью) отвечает за все визуальные аспекты приложения. Для отображения данных пользователю мы использовали React.
При первой загрузке приложения на экране отображается приветственное сообщение.
При нажатии кнопки «View Dashboard» происходит переход к таблице тренеров и списку отсутствующих документов.
Компонент Вид не взаимодействует напрямую с базой данных, поскольку это делает наш контроллер. Контроллер предоставляет эту информацию компоненту представление, чтобы ее можно было отобразить на странице.
Вот как выглядит код, когда представление выполняет вызов выборки (fetch) для получения данных от контроллера:
await fetch('https://mvc-project-backend.herokuapp.com/coaches')
Затем мы используем метод map() , чтобы пройтись по списку тренеров и отобразить их имена, адреса электронной почты и программу в виде таблицы.
coachData.map(data => ( > ))
Для отображения раздела отсутствующих документов мы отправляем запрос к бэкнэду и получием список тренеров, которые не заполнили анкету, не сдали тесты на туберкулез, не привиты от Covid и не прошли проверки.
Для отображения имен для каждой категории снова используется метод map() .
Если нажать кнопку «Send reminder email», эта информация будет отправлена React-ом на бэкэнд. Контролер отвечает за отправку сообщения электронной почты и обмен информацией с компонентом представление о том, отправилось ли сообщение.
На основе информации, которую он получает от контроллера, во View отображается сообщение об успехе или сообщение об отказе.
Компонент Controller
Контроллер взаимодействует с компонентами «Модель» и «Представление» и выполняет все логические операции для нашего приложения. Этот раздел кода был построен в Node.JS и Express.
Контролер получает полный список тренеров из «Модели» и отправит эту информацию в «Представление». Контролер также отвечает за фильтрацию через «Модель» и предоставление списка тренеров, которые не сдали необходимые документы.
Все эти данные отправляются в «Представление», чтобы их можно было отобразить пользователю.
Что касается функциональности электронной почты, то «Контролер» перед отправкой проверяет валидность адреса электронной почты.
Для отправки электронных писем использована Nodemailer :
transporter.sendMail(mailOptions, (err) => < if (err) < console.log(`Applications: There was an error sending the message: $`) res.json(< status: 'Email failure' >) > else < console.log(`Applications Success: Email was sent`) res.json(< status: "Email sent" >); > >)
Если сообщение электронной почты успешно отправлено, пользователь получает уведомление, и сообщение электронной почты отображается в почте демонстрационной учетной записи.
Если при отправке сообщения возникает ошибка, то «Контроллер» посылает эту информацию в «Вид», чтобы пользователю отобразилось уведомление об ошибке.
Заключение
А в заключение повторим пройденное:
- Model-View-Controller — популярный шаблон программирования, используемый для разделения логики приложения на три различных компонента.
- Хотя шаблон MVC первоначально использовался в настольных приложениях, в конце 1990-х он стал популярным в разработке веб-приложений.
- Модель отвечает за логику данных, лежащую в основе приложения.
- Представление — это то, что пользователь видит в приложении и взаимодействует с ним.
- Контроллер действует как мозг приложения и взаимодействует с моделью и представлением.
- Веб-инфраструктуры, использующие шаблон MVC — это Ruby on Rails, ASP.NET MVC, Laravel и Angular.
Контроллеры
Контроллер является центральным компонентом в архитектуре MVC. Контроллер получает ввод пользователя, обрабатывает его и посылает обратно результат обработки, например, в виде представления.
При использовании контроллеров существуют некоторые условности. Так, по соглашениям об именовании названия контроллеров должны оканчиваться на суффикс «Controller», остальная же часть до этого префикса считается именем контроллера.
Чтобы обратиться контроллеру из веб-браузера, нам надо в адресной строке набрать адрес_сайта/Имя_контроллера/ . Так, по запросу адрес_сайта/Home/ система маршрутизации по умолчанию вызовет метод Index контроллера HomeController для обработки входящего запроса. Если мы хотим отправить запрос к конкретному методу контроллера, то нужно указывать этот метод явно: адрес_сайта/Имя_контроллера/Метод_контроллера , например, адрес_сайта/Home/Buy — обращение к методу Buy контроллера HomeController.
Контроллер представляет обычный класс, который наследуется от базового класса System.Web.Mvc.Controller . В свою очередь класс Controller реализует абстрактный базовый класс ControllerBase, а через него и интерфейс IController . Таким образом, формально, чтобы создать свой класс контроллера, достаточно создать класс, реализующий интерфейс IController и имеющий в имени суффикс Controller.
Интерфейс IController определяет один единственный метод Execute, который отвечает за обработку контекста запроса:
public interface IController
Теперь создадим какой-нибудь простенький контроллер, реализующий данный интерфейс. В качестве проекта мы можем взять проект из предыдущий главы. Итак, добавим в папку Controllers проекта новый класс (именно класс, а не контроллер) со следующим содержанием:
using System.Web.Mvc; using System.Web.Routing; namespace BookStore.Controllers < public class MyController : IController < public void Execute(RequestContext requestContext) < string ip = requestContext.HttpContext.Request.UserHostAddress; var response = requestContext.HttpContext.Response; response.Write("Ваш IP-адрес: " + ip + "
"); > > >
При обращении к любому контроллеру система передает в него контекст запроса. В этот контекст запроса включается все: куки, отправленные данные форм, строки запроса, идентификационные данные пользователя и т.д. Реализация интерфейса IController позволяет получить этот контекст запроса в методе Execute через параметр RequestContext . В нашем случае мы получаем IP-адрес пользователя через свойство requestContext.HttpContext.Request.UserHostAddress .
Кроме того, мы можем отправить пользователю ответ с помощью объекта Response и его метода Write.
Таким образом, перейдя по пути адрес_сайта/My/ , пользователь увидит свой ip-адрес.
Хотя с помощью реализации интерфейса IController очень просто создавать контроллеры, но в реальности чаще оперируют более высокоуровневыми классами, как например класс Controller, поскольку он предоставляет более мощные средства для обработки запросов. И если при реализации интерфейса IController мы имеем дело с одним методом Execute, и все запросы к этому контроллеру, будут обрабатываться только одним методом, то при наследовании класса Controller мы можем создавать множество методов действий, которые будут отвечать за обработку входящих запросов, и возвращать различные результаты действий.
Чтобы создать стандартный контроллер, мы можем также добавить в папку Controllers простой класс и унаследовать от класса Controller, например:
using System.Web.Mvc; namespace BookStore.Controllers < public class BookShopController : Controller < public ActionResult Index() < return View(); >> >