Паттерн MVC. Объяснение на примере лего

В этом посте будут объяснены принципы Model-View-Controller на примере всеми нам знакомого и любимого конструктора "Лего".


Лего!

Представьте. Вам десять лет, вы сидите на полу у себя дома и перед вами большая коробка Лего. Там есть элементы всех различных форм и размеров. Одни синие, высокие и продолговатые. Как прицеп грузовика. Другие красные и кубические. А некоторые желтые - большие широкие листы. С учетом всех этих различных типов лего, вы могли бы построить все что угодно.

Но вот сюрприз, уже есть запрос. Ваш старший брат вбегает и говорит, "Эй! Построить мне космический корабль! "

"Хорошо," Вы думаете, "что на самом деле может быть довольно прикольно!".

Таким образом, вы получите работу. Вы начинаете вытаскивать лего и думать, что вам нужно. Одни большие, другие маленькие. Одни цвета для обшивки корабля, другие для двигателей. Ах да, и другие цвета для бластеров. (У вас должны быть бластеры!)

Теперь у вас есть все ваши элементы лего под рукой, пора собрать космический корабль. И после нескольких часов напряженной работы перед вами - космический корабль!

Вы бежите и ищете вашего брата, чтобы показать ему готовый продукт. "Ничего себе, хорошая работа!", Говорит он. "Хмм...," он думает, "я просто попросил это пару часов назад, ничего не делал, и вот оно!. Я хочу чтоб все было так просто!".

А что, если я скажу вам, что создание веб-приложения это же что и строительство из лего?



Все начинается с запроса ...

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

Таким образом, ваш брат пользователь.



Запрос достигает контроллера(controller) ...

С лего вы - контроллер.
Контроллер отвечает за сбор всех необходимых строительных блоков и организацию их по мере необходимо.



Эти строительные блоки ни что иное как модели(model).

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



Таким образом, запрос приходит ...

Контроллер (вы) принимает запрос.
И переходит моделям(лего), чтобы получить необходимые предметы.
И теперь все на месте, чтобы произвести конечный продукт.



Конечный продукт известен как представление(view) ...

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



В итоге:

При строительстве из лего:

  1. Ваш брат делает запрос, на строительство космического корабля.

  2. Вы получите запрос.

  3. Вы достаете и организовываете все детали лего, необходимые для строительства космического корабля.

  4. Вы используете лего, для того чтобы построить космический корабль и представить готовый корабль вашему брату.

mvc_lego2

И в веб-приложении:

  1. Пользователь запрашивает просмотр страницы, введя URL-адрес.

  2. Контроллер получает этот запрос.

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

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

mvc_lego3

Посмотрим с более технической точки зрения

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

Когда вы вводите URL в вашем браузере, вы делаете запрос на просмотр определенной страницы в приложении. Но как приложение узнает, какую страницу отрисовать?

При создании веб-приложения, вы определяете так называемые маршруты(routes). Маршруты, по сути, шаблоны URL, связанные с разными страницами. Поэтому, когда кто-то вводит URL, приложение пытается сопоставить этот адрес с одним из  предопределенных маршрутов.

Так что на самом деле имеется основных компонента: маршруты
(routes), модели(models), представления(view) и контроллеры(controllers).



Маршруты (Routes)

Каждый маршрут связан с контроллером, а если более конкретно - с определенной функции внутри контроллера (controller action). Так что, когда вы вводите URL, приложение пытается найти соответствующий маршрут, и, если это находит, то он вызывает связанный с этим маршрутом controller action.

Давайте рассмотрим простой маршрут во flask в качестве примера:

@app.route('/')
def index():
    pass
Здесь мы ассоциируем route / с функцией представления index


Модели и контроллеры (Models and controllers)

В controller action, как правило, происходят две основные вещи:

  • модели используются для получения всех необходимых данных из базы данных;
  • данные передаются представлению(view), для отрисовки запрошеной страницы.

Данные, полученные моделью(model), как правило, виде в структурированных данных (например, список или словарь) направляются в представление(view).

Вернемся к нашему примеру на flask


@app.route('/')
def index():    
    blocks = Blocks.object().all()
    return render_template('index.html', blocks=blocks)

В настоящее время в функции представления, мы список блоков из базы данных. Этот список мы помещаем в переменную, которая будет доступна в шаблоне index.html.



Представления (View)

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

Опять же, вернемся к нашему примеру на flask. Здесь используя синтаксис Jinja, мы перебираем записи в списке blocks, чтобы отобразать каждую из них.


{% for entry in entries %}
  <li>
    <h2>{{ entry.title }}</h2>
    <div>{{ entry.text|safe }}</div>
  </li>
{% else %}
  <li><em>No entries yet. Add some!</em></li>
{% endfor %}


Резюме

Таким образом, подытожим описание паттерна MVC с технической стороны:

  • Запрос пользователя на просмотр страницы, посредством ввода URL-адреса.
  • Приложение соотносит URL с маршрутом(route).
  • Вызывается controller action, связанный с маршрутом.
  • controller action использует модели(models) для получения всех необходимых данных из базы данных, помещает данные в массив, и передает представлению(view).
  • Представление получает доступ к данным и использует их, для отрисовки запрошенной страницы, которая затем показывается пользователю в браузере.

Данная статья является переводом. Оригинал Здесь.