MVC в WordPress

У программистов часто возникает спор о том что такое MVC (Model, View, Controller)?

Заметил что многие думают что если класс назвать Model то он станет Model, а если его назвать View, то он станет View. А если папочку назвать MVC то вот у нас уже свой MVC 🙂 Мозг слишком залипает в слова и за словами не видит реальности.

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

Думаю для многих будет сюрпризом узнать что в WordPress написан с учетом MVC 🙂 Просто классы там не называются как Model, Controller и View имеет иное название. А раз программисты не очень хорошо понимают особенности этих паттернов, то им кажется что в WordPress нет MVC.

Что такое MVC?

MVC — это набор паттернов, который разбивают логику работы на 3 части:

  • models — объекты отвечающие за логику работы с сущностями, как правило их свойства ассоциируются с полями таблицы БД, а методы состоят преимущественно из геттеров и сеттеров
  • views — это шаблоны представления данных 🙂 по сути у них есть второе название — templates
  • controllers — объекты которые отвечают за получение данных, их обработку и иногда передачу в views (templates)

Подробнее про Views

Есть программисты которые путают View и контроллер который работает с View. Особенно в WordPress.

Если посмотреть View в Laravel или RoR, то можно увидеть что они повторяют логику работы с templates в WP (метод get_template_part).

В Symfony 3 эта механика тоже называлась View, но в версии Symfony 4 они переименовались в templates и стали походить на то как это сделано в WP.

Возможно это было сделано как раз по причин того чтобы снизить путаницу в голове у программистов.

Подробнее про Models

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

Например класс WC_Product в WooCommerce это классическая модель. У нее есть ID и другие свойства согласно таблице.

Методы такого класса в основном состоят из геттеров и сеттеров.

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

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

Например class Property extend Model … так мы создали модель для Недвижимости и можем работать с объектами недвижимости. Если мы в Ларавел.

В WP нет базового класса Model, и мы просто создаем class Property, дописывая туда то что нам нужно — обычно надо писать геттеры и сеттеры. Чуть более трудоемко и нужно чтобы программист понимал что такое Model 🙂 Трудоемкость условно выше на пару часов, гораздо сложнее с пониманием. Мало кто из программистов хорошо понимает что такое Model и вот тут обычно возникают все проблемы 🙂

Многие плагины и задачи в WP могут быть решены вообще без образования моделей. Потому что там многие задачи решаются через единую модель WP_Post. И для большинства задач этого хватает. У этой модели есть редкая особенность, о которой мы поговорим далее…

Пример хорошей реализации правильной модели это класс WC_Product в WooCommerce. Это классическая модель. Которая как то работает без наследования от базового класса Model. По всем признакам это модель. Но тк нет наследования от одноименного базового класса — у программистов может возникнуть разрыв шаблона и подгорание пукана.

Подробнее про Controllers

Легче понять что такое View и Model, и все что не влазит в View и Model — может быть размещено в Controller. По сути это все другие классы. Которые обеспечивают логику работы приложения. Хотя конечно типы и паттерны классов не ограничены лишь Моделями и Контроллерами. Существует множество других классов по иным паттернам. Например попробуйте угадать какому паттерну соответствует класс DateTime? 🙂 Это не модель, не контроллер и тем более не view/template. Классы бывают разные и не всегда они должны называться контроллерами или быть моделями 🙂

Потому обычно контроллером называется класс, который принимает и обрабатывает данные. Обычно он возвращает данные в представление (view/template) или в JSON API. А может быть и ничего не возвращает. Принял, сохранил и уснул 🙂 Так тоже бывает.

Почему WP_Post без возможности наследования?

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

Это сделано по причине экономии запросов к БД на сайтах без объектного кеша (Redis/Memcached…). При создании объекта модели (например Product), у нас срабатывает конструктор, который забирает данные из базы и сохраняет их в состояние класса (свойства класса получают значения из БД). Но в коде у нас на 1 запросе может быть множество мест где мы создаем объект. Если у нас нет объектного кеша — каждый такой объект займет память и сделает запрос в БД. А это дорого и нагрузка. Надо чтобы при каждом создании объекта, если он уже был создан ранее — не нужно было запускать конструктор и снова запрашивать данные в базе. Именно эту проблему можно решить если наш класс будет Синглтоном или как в случае с WP_Post используется механика кеширования без наследования. А тк WP рассчитан на то чтобы работать в том числе на простых сайтах где нет объектного кеша — это единственный способ обеспечить снижение нагрузки на БД.

Но как быть с наследованием? Тут все просто. Надо включить мозг и понять что такое модель 🙂 Например тот же WC_Product это унаследованная модель продукта, которая базируется на WP_Post. Никто не мешает создать любую модель, которая может содержать в себе данные WP_Post из таблицы posts и если нужно то какие то данные из post_meta, а при желании подцепить любые кастомные таблицы.

Вариантов решений тут много. Было бы понимание что такое Model, а найти решение уже не составит труда.

Итого

За последнее время я лучше стал понимать что такое MVC. Видел разные варианты реализации: RoR, Laravel, Symfony, WP. У всех вариантов есть свои особенности, плюсы и минусы. Но в этой части я не готов говорить какой вариант реализации MVC лучше. Мне кажется это не возможно.

Единственное что мне кажется странным, это то что программисты не разобравшись в том что есть MVC — пытаются утверждать что этого нет в WP 🙂 Городят разные костыли, называя их MVC. Порой эти костыли выглядят очень странно и смешно. А доказать людям что их MVC ничем не лучше той что уже есть в WP — достаточно сложно.

Хороший пример на мой взгляд это WooCommerce. Там все сделано красиво. Люди которые пилят этот продукт — реально понимают что такое MVC. Там правильно сделаны модели Продуктов и Заказов, там правильно используется представления (View/Template). Мне нравится как там реализованы многие контроллеры на простых классах со статическими методами. И ребята не залипают в иллюзиях.

Источник: https://wpcraft.ru/notes/mvc-v-wordpress/

Анатолий Юмашев

Настоящий шаман, планирует жить до 150 лет. Родом из Тюмени, жил в Санкт-Петербурге, Москве и землянке (по его словам). Думает, что знает WordPress лучше всех в мире, кроме еще 10 человек. Делает всякие безумные вещи, которые иногда даже работают. Может зарядить или полностью отнять энергию у 50 человек. Один из ярких участников российского WordPress сообщества, а также создатель самого продаваемого и обсуждаемого плагина для синхронизации Woocommerce и МойСклад. Умеет исчезать сквозь землю. Любит WordPress, кальян, сигары и Льва Толстого. Может жить и работать вообще без еды. Делает сайты от 10 млн рублей.

Добавить комментарий

%d такие блоггеры, как: