Статьи

MVC для нубов

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

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

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

Дикая популяризация этой структуры для веб-приложений обусловлена ​​ее включением в две очень популярные платформы разработки: Struts и Ruby on Rails. Эти две среды отметили путь для сотен фреймворков, созданных позже.

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

Приложение разделено на три основных компонента, каждый из которых отвечает за выполнение различных задач. Давайте посмотрим подробное объяснение и пример.

Контроллер управляет пользовательскими запросами (полученными в виде запросов HTTP GET или POST, когда пользователь нажимает на элементы GUI для выполнения действий). Его основная функция — вызывать и координировать необходимые ресурсы / объекты, необходимые для выполнения действий пользователя. Обычно контроллер вызывает соответствующую модель для задачи, а затем выбирает правильный вид.

Модель — это данные и правила, применяемые к этим данным, которые представляют понятия, которыми управляет приложение. В любой программной системе все моделируется как данные, которые мы обрабатываем определенным образом. Что такое пользователь, сообщение или книга для приложения? Только данные, которые должны обрабатываться в соответствии с определенными правилами (дата не может быть в будущем, электронная почта должна иметь определенный формат, имя не может быть длиннее x символов и т. Д.).

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

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

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

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

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

У нас будет специальный контроллер для обработки всех действий, связанных с книгами (просмотр, редактирование, создание и т. Д.). Давайте назовем это books_controller.php для этого примера. У нас также будет модель, например book_model.php, которая обрабатывает данные и логику, связанные с товарами в магазине. Наконец, у нас будет ряд представлений, например, список книг, страница для редактирования книг и т. Д.

На следующем рисунке показано, как обрабатывается запрос пользователя на просмотр списка книг с фантазиями:

Контроллер (books_controller.php) получает запрос пользователя [1] в виде запроса HTTP GET или POST (у нас также может быть центральный контроллер, например index.php, получающий его и затем вызывающий books_controller.php).

Контроллер проверяет запрос и параметры и вызывает модель (book_model.php), предлагая ему вернуть список доступных книг о фэнтези [2].

Модель отвечает за получение этой информации из базы данных (или где бы она ни хранилась) [3], применяет фильтры или логику, если необходимо, и возвращает данные, представляющие список книг [4].

Контроллер будет использовать соответствующий вид [5] для представления этих данных пользователю [6-7]. Если запрос поступил с мобильного телефона, будет использоваться представление для мобильных телефонов, если у пользователя выбран конкретный скин, будет выбран соответствующий вид и т. Д.

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

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

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

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

Возьмите cakePHP в качестве примера MVC Framework. После установки вы увидите три основных каталога:

  • приложение/
  • торт/
  • поставщики /

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

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

Папка vendors предназначена для сторонних библиотек PHP, если это необходимо.

Ваше рабочее место (каталог приложений) имеет следующую структуру:

  • приложение/
    • конфиг /
    • контроллеры /
    • национальная_версия /
    • модели /
    • плагины /
    • Тесты /
    • TMP /
    • поставщики /
    • взгляды/
    • Webroot /

Теперь вы должны поместить ваши контроллеры в каталог контроллеров , ваши модели в каталог моделей, а ваши представления в … каталог представлений!

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

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

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

Итак, когда пользователь нажимает, браузер будет запрашивать этот URL:

1
www.ourstore.com/books/list/fantasy

CakePHP любит форматировать URL-адреса в форме / controller / action / param1 / param2, где action — это функция, вызываемая внутри контроллера. В старом классическом формате URL это будет:

1
www.ourstore.com/books_controller.php?action=list&category=fantasy

С помощью платформы cakePHP наш контроллер будет выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<?php
 
class BooksController extends AppController {
 
 function list($category) {
 
 $this->set(‘books’, $this->Book->findAllByCategory($category));
 
 }
 
 function add() { … … }
 
 function delete() { … … }
 
 … … } ?>

Просто, не правда ли? Этот контроллер будет сохранен как books_controller.php и помещен в / app / controllers. Он содержит функцию списка для выполнения действия в нашем примере, а также другие функции для выполнения других действий, связанных с книгой (добавление новой книги, удаление новой книги и т. Д.).

Фреймворк предоставляет нам много всего, и для перечисления книг необходима только одна строка. У нас есть базовые классы с базовым поведением контроллера, уже определенным, поэтому мы наследуем их (AppController, который наследует от Controller).

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

эта-> книга — наша модель, и эта часть:

1
$this->Book->findAllByCategory($category)

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

Заданный метод в строке:

1
$this->set(‘books’, $this->Book->findAllByCategory($category));

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

Теперь нам просто нужно отобразить представление, но это будет сделано автоматически при помощи cakePHP, если мы хотим представление по умолчанию. Если нам нужен какой-либо другой вид, мы просто должны вызвать его явно, используя метод render .

Модель еще проще:

1
2
3
4
5
6
7
<?php
 
class Book extends AppModel {
 
}
 
?>

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

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

Код будет сохранен как book.php и помещен в / app / models.

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

1
2
3
4
5
<table> <tr> <th>Title</th> <th>Author</th> <th>Price</th> </tr>
 
<?php foreach ($books as $book): ?> <tr> <td> <?php echo $book[‘Book’][‘title’];
 
</table>

Как мы видим, представление не производит полную страницу, только фрагмент HTML (в данном случае таблицу). Это связано с тем, что CakePHP предоставляет другой способ определения макета страницы, и представления вставляются в этот макет. Фреймворк также предоставляет нам несколько вспомогательных объектов для упрощения общих задач при создании этих HTML-фрагментов (вставка форм, ссылок, Ajax или JavaScript).

Мы делаем это представлением по умолчанию, сохраняя его как list.ctp (list — это имя действия, а ctp означает шаблон торта) и помещая его в / app / views / books (внутри books, потому что это представления для действий контроллера книг).

И это завершает три компонента с помощью фреймворка CakePHP!

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

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