Битрикс, HMVC и щепотка бреда…
Здрасте! Наверняка многие знают, что такое CMS Битрикс, что она из себя представляет и какие «замечательные» код и архитектурные решения представляют его разработчики. В данном посте я хотел бы предложить новое видение на разработку компонентов и модулей системы.
HMVC
Прежде чем объяснять, что это за 4 буквы, напомню, что значат последние три:
Собственно MVC — это шаблон проектирования, который разделяет систему на три части:
- Модель — бизнес-логика;
- Контроллер — логика управления/взаимодействия;
- Представление — UI.
Плюсы этого шаблона в том, что если он нормально реализован, то бизнес-логика полностью независима от C и V. Кому нужны подробности и кто по каким-то причинам до сих пор не знает что это такое — вперед в google.
Вроде бы все хорошо, MVC прям почти панацея (это такая вещь, которая решает все проблемы), но если система достаточно большая, то она неизбежно усложняется и как следствие (или причина) возникают проблемы масштабирования. Тут на помощь приходит добрый друг: H — Hierarchical.
Основная идея данного шаблона в том, что вся система делиться на отдельные, независимые триады (MVC’шки), которые общаются между собой через контроллеры. Таким образом бизнес-логика по прежнему изолирована от внешнего мира, и по сути система самопроизвольно дробиться на мелкие части, а это куда удобнее и проще спагетти-зависимостей, которые неизбежно возникнут в большой системе.
Общение триад происходит путем запросов к контроллерам. Можно выделить следующие виды запросов:
- внешний запрос — создание запроса к другому серверу (божественное распределение);
- внутренний запрос — создание запроса к текущему серверу;
- вызов функции — просто вызов действия контроллера из кода, без дополнительного запроса к серверу.
Битрикс и его тараканы
Битрикс — это крайне разрекламированная и крайне недружелюбная для разработчика система управления. Но на самом деле речь не об этом, поэтому перейдем к делу.
По заявлению авторов, данная система реализует шаблон MVC. Выглядит это следующим образом:
Эмм… серьезно? Модель находиться в другой структурной части системы, отдельно от контроллера и представления. Отдельно, Карл!!!
На самом деле это довольно удачный ход, т.к. вся система основана на компонентах и каждый из них может дергать любую модель, любого модуля, а если быть точным конкретную модель — инфоблоки. Но как по мне с точки зрения MVC это неверно, контроллеры перегружаются логикой (по крайней мере если смотреть на реализацию стандартных компонентов).
Битрикс. Модели
Инфоблоки — это очень удобное и гибкое решение для хранения информации, тут не поспоришь и игнорировать данный инструмент — глупо. Для наглядности, структуру системы в общем случае можно изобразить так:
Глядя на эту картинку можно сделать вывод, что решение отделить модель чертовски замечательное. Но в данном случае много логики в контроллерах (компонентах), а модели (API) это всего лишь domain model, и никакой логики не содержат.
Битрикс. Контроллеры
Битрикс заверяет нас, что компоненты выполняют роль контроллеров, но я не соглашусь с этим.
Компоненты — это виджеты: они получают на вход данные и каким-либо образом их преобразуют.
Комплексные компоненты — это контроллеры (точнее фронт контроллеры): они принимают на вход запрос пользователя, парсят его и инициируют запрошенное действие. Схематически это можно выразить так:
Битрикс. HMVC
С представлением битрикс об MVC мы познакомились, теперь рассмотрим варианты общения контроллеров (компонентов) между собой.
Как советует нам документация: общаться компонентам можно либо через глобальные переменные, либо через события. На самом деле это советы по кооперации модулей, но строго говоря на компоненты они тоже применимы, вот только не совсем подходят:
- глобальные переменные — неявная передача данных;
- события — вообще мимо кассы.
Так что на мой взгляд оптимальным будет передача параметров по ссылке:
$APPLICATION->IncludeComponent('comp1','',[& $params]);
$APPLICATION->IncludeComponent('comp2','',[$params]);
// либо если явно указывать что есть что
$APPLICATION->IncludeComponent('comp1','',['request' => $req, 'response' => & $res]);
$APPLICATION->IncludeComponent('comp2','',[$res]);
?>
Все прозрачно и понятно куда, что и когда поступает.
Вроде бы все, но нет. Каждый отдельный компонент (не комплексный) должен представлять собой отдельную триаду MVC, а этого строго говоря нет. На помощь приходит service layer:
Благодаря такой структуре каждый компонент (не комплексный) имеет свою модель (service layer), с необходимой бизнес-логикой, которая в свою очередь обращается к API (domain model) для работы с базой.
Немного бреда
Конечно можно было бы закончить статью пунктом выше, но эмоции рвутся наружу поэтому я не могу молчать. Меня очень забавляет тот факт, что все битриксоиды, не зависимо от их уровня профессионализма кричат в один голос «используйте все из коробки, если этого в коробке нет, не используйте битрикс вообще!». Спрашивается «Зачем тогда маркетплейс?», ну да ладно.
Ребят, серьезно? Вы разработчики или кто? Я понимаю что битрикс это некий конструктор (угадайте чье это мнение) в котором МНОГО что есть, но секундочку: много — это НЕ ВСЕ. И мне несказанно грустно когда битриксоиды говорят используйте стандартные модули и на их основе делайте что-то.
Я не призываю переписывать все модули и лепить кучу велосипедов (хотя маркетплейс ими изобилует). Для прокачки скилла конечно стоит написать пару своих велосипедов, но из стандартных модулей можно взять только API и не более, потому как в жизни я не видел хуже говнокода, но это Битрикс, с этим ничего не поделать.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.