Понимание MVC очень важно знать, если вы хотите иметь возможность организовать свои приложения очень чистым способом.

Так что же это за штука MVC и почему о ней так часто говорят?👀

Проще говоря, MVC (Модель, Вид, Контроллер) — это способ мышления при создании или структурировании наших приложений. Об этом часто говорят, потому что это один из стандартных подходов при создании приложения. Давайте углубимся в MVC в отношении веб-приложений.

Разберем MVC

Представьте, что кто-то заходит в Google и ищет все типы автомобилей. На скриншотах я хочу, чтобы вы обратили внимание на две вещи. Первый — это то, как выглядит URL-адрес до того, как человек нажмет «Поиск», а второй — после того, как пользователь нажмет «Поиск».

URL Перед тем, как пользователь нажмет поиск

В настоящее время URL-адрес просто https://www.google.com/. Давайте посмотрим, что происходит, когда пользователь нажимает кнопку поиска, чтобы найти информацию об автомобилях.

URL После того, как пользователь нажмет кнопку поиска

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

Маршрутизатор

Таким образом, маршрутизатор является частью шаблона MVC, хотя у него нет собственной конкретной буквы в аббревиатуре. Роутер выполняет ОДНУ работу и справляется с ней очень хорошо. Задача маршрутизатора состоит в том, чтобы просмотреть URL-адрес (когда пользователь делает запрос) и передать эту информацию соответствующему контроллеру.

Давайте посмотрим на код!

Модель MVC может применяться ко многим различным языкам, но давайте, например, воспользуемся JavaScript (NodeJS/ExpressJS).

Итак, у нас есть базовый сервер Node:

const express = require('express')
const app = express()
const connectDB = require('./config/database')
**const homeRoutes = require('./routes/home')**
const todoRoutes = require('./routes/todos')
require('dotenv').config({path: './config/.env'})
connectDB()
app.set('view engine', 'ejs')
app.use(express.static('public'))
app.use(express.urlencoded({ extended: true }))
app.use(express.json())
**app.use('/', homeRoutes)**
app.use('/todos', todoRoutes)
app.listen(process.env.PORT, ()=>{
    console.log('Server is running, you better catch it!')
})

Вы не обязаны понимать все, что происходит. Давайте просто сосредоточимся на двух строках кода, которые отмечены звездочкой.

Первая строка:

const homeRoutes = require('./routes/home')

по сути, это просто импорт модуля и его сохранение в переменной для последующего использования. В этом смысле модуль — это просто каталог внутри вашего проекта.

Итак, теперь, когда вы это знаете, давайте посмотрим на следующую важную строку кода:

app.use('/', homeRoutes)

P.S. app.use — это всего лишь промежуточное ПО, а промежуточное ПО — это, по сути, то, что происходит (логика, функциональность и т. д.) в ПОСЛЕДНЕМ запросе и ответе.

Итак, эта строка просто говорит: «Эй, сервер, когда кто-то делает запрос к корневому маршруту («/» — это корневой маршрут), перейдите к homeRoutes, чтобы наш маршрутизатор homeRoutes мог отправить эту информацию соответствующему контроллеру». Помните, что homeRoutes — это переменная, указывающая на модуль (каталог в вашем проекте).

Поэтому, когда пользователь переходит на корневой маршрут (например, www.something.com/), сервер знает, что делать, то есть переходить на маршрутизатор, созданный для корневого маршрута. Теперь давайте посмотрим, что происходит, когда мы на самом деле добираемся до того места, где находится маршрутизатор.

P.S. маршрутизатор обычно находится внутри каталога (папки) Routes

Смотрим на наш роутер

const express = require('express')
const router = express.Router()
const homeController = require('../controllers/home')
router.get('/', homeController.getIndex) 
module.exports = router

Я не хочу слишком много сосредотачиваться на коде, а скорее на концепции высокого уровня, поэтому я просто сосредоточусь на самой важной части кода.

router.get('/', homeController.getIndex)

Это роутер. Это то, что знает, что делать, когда пользователь делает запрос. Этот маршрутизатор говорит: «Хм, я вижу, что пользователь сделал запрос GET к корневому маршруту, и я точно знаю, на какой контроллер (homeController) отправить этот запрос, чтобы они могли это обработать! Я знаю не только контроллер, которому нужно отправить это, но и метод, который контроллер собирается использовать для обработки этого (getIndex)». Помните, что ЕДИНСТВЕННАЯ РАБОТА маршрутизатора состоит в том, чтобы просмотреть URL-адрес (и тип запроса) и отправить эту информацию соответствующему контроллеру для обработки.

P.S. помните переменную, которая была установлена ​​в коде сервера, чтобы указать, откуда берется модуль (каталог)? Та же концепция с переменной homeController

MV(C) - C для контроллера

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

module.exports = {
    getIndex: (req,res)=>{
        res.render('index.ejs')
    }
}

В этом коде контроллер получил информацию (запрос) от маршрутизатора, и вот КАК ОН ОТВЕЧАЕТ (помните, все в Интернете — это просто запросы и ответы). Так что, по сути, это просто РЕНДЕРИНГ ВИДА. Таким образом, контроллер говорит: «Эй, маршрутизатор, спасибо за эту информацию, на основе этого запроса все, что мне нужно сделать, это пойти и сказать представлению, что с этим делать».

M(V)C — буква V предназначена для просмотра

Работа ТОЛЬКО для просмотра состоит в том, чтобы принимать информацию, которую отправляет контроллер, и представлять ее клиенту (браузеру). В этом случае представление просто будет отображать некоторые ejs, которые просто выплевывают некоторый html-код. Я думаю, что представление легче всего понять, потому что это то, что мы видим, когда заходим в Интернет каждый день. Этот пост в блоге, который вы читаете, является просто просмотром! Теперь, когда мы это понимаем. Посмотрим на модель.

(M)VC - М для модели

Это может быть пугающим для понимания, но я постараюсь сделать это как можно проще! Задача модели — определить структуру данных. Модель — это то, что взаимодействует с базой данных, чтобы получить любую информацию, которую запрашивает контроллер, а также выполняет удаление, вставку, обновление или выборку из базы данных. Давайте подумаем о примере Google из предыдущего. Когда кто-то ищет автомобили и нажимает ввод, маршрутизатор отправляет запрос контроллеру, а контроллер спрашивает модель: «Эй, модель, можешь дать мне ВСЮ информацию об автомобилях, которая у тебя есть?» Затем модель проверяет базу данных и говорит: «Вот вся информация, которую хранит база данных».

Надеюсь, теперь вы лучше понимаете, как работает MVC на высоком уровне. Если вы все еще запутались, посмотрите это видео (https://www.youtube.com/watch?v=1IsL6g2ixak&t=639s), чтобы лучше понять.

Не стесняйтесь подписаться на эти социальные сайты:
Twitter: https://twitter.com/NickAHollins
LinkedIn: https://www.linkedin.com/in/nicholas- Холлинс/