Оригинал: Copyright © 2013 Akeeba Ltd
Перевод: Copyright © 2014 Фёдоров Александр

Содержание данной документации, являюется объектом авторского права и доступно согласно лицензии Joomla! Electronic Documentation License (JEDL), если не указано иное. Вы можете обратиться к разделу частые вопросы по JEDL, чтобы уточнить как вы можете использовать данный материал. Если у вас есть какие-либо вопросы, касающиеся лицензирования данного материала, или вы хотите сообщить о возможном нарушении условий лицензии на материалы данного сайта, пожалуйста, напишите по электронной почте: Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра..

FOF - это MVC фреймворк по сути и духу. Он старается как можно полнее соответствовать MVC соглашениям, начиная с Joomla! 1.5 и убирая где возможно ненужное дублирование кода. Основная цель - это придерживаться концепции DRY (Don’t Repeat Yourself - не повторяйся). Отследить это просто: если возникло желание скопировать часть кода из базового класса и вставить его в другой класс, значит что-то идёт не так.

Для достижения нужной изоляции кода, FOF использует гибкую структуру компонента, как на иллюстрации:

Структура компонента

Диспетчер - это входная точка компонента. Некоторые могут назвать его "фронт Контроллером" и будут правы. Но здесь есть и некоторые различия. Диспетчер - это интерфейс, связывающий ваш компонент с приложением (например, Joomla! CMS). Он решает какой контроллер и какую задачу надо запустить основываясь на входных данных, далее инициализирует этот контроллер, передаёт в него данные и управление. Контроллер должен вернуть Диспетчеру либо данные для возврата в приложение, либо вызов следующего контроллера и т.д.

Теперь давайте разберёмся что такое Контроллер и где он? На схеме под блоком Диспетчер находится так называемая "триада". Каждая триада отвечает за отдельную сущность в вашем компоненте. Например, одна триада может отвечать за клиентов, другая за заказы и т.д. Компонент может состоять из одной или более триад. Каждая триада обычно состоит из Контроллера, Модели и Вида ("триада" и расшифровывается как "состоящая из трёх"). Обязательным в триаде является только Контроллер. Триада может повторно использовать Модель или Вид из другой триады - это ещё один довод в пользу DRY. Или триада, например, может быть без Вида. Т.е. триада может состоять из одного (Контроллера), двух (Контроллер и Модель) или трёх элементов. Далее автор предлагает отказаться от термина "триада" и заменить его на "вид" с маленькой буквы, мы этого делать не будем и продолжим пользоваться термином "триада" - прим. переводчика.

Триады в FOF следуют парадигме "толстая Модель - тонкий Контроллер". Это означает, что Контроллер зачастую содержит небольшой объём кода, в то время как Модель выполняет всю основную работу. Удерживая этот важный момент в памяти, взглянем на внутреннюю организацию триады.

В самом начале у нас есть Контроллер. В Контроллере описаны одна или более задач. Каждая задача - это некоторое действие в компоненте - отобразить список записей, показать одну запись, опубликовать, удалить запись и т.д. Но есть небольшое уточнение - Контроллер не выполняет никакой работы. Он только вызывает экземпляр Модели и передаёт в него необходимые данные. Это называется "задать состояние" Модели. В большинстве случаев Контроллер также вызывает какой-нибудь метод Модели, в котором выполняются определённые действия с данными. Крайне важно заметить, что Контроллер может работать с любой Моделью, в которой описан нужный метод, а Модель в свою очередь ничего не знает о Контроллере. После инициализации Модели Контроллер инициализирует экземпляр Вида и передаёт в него Модель для отображения выводимых данных. Затем Контроллер получает от Вида данные для выдачи в приложение и передаёт их Диспетчеру.

Теперь мы подошли к Модели. Модель - это "рабочая лошадка" триады, именно в ней обрабатывается вся бизнес-логика. Все Модели в FOF являются пассивными, это означает, что им обязательно нужны Контроллер и Вид. Более того, Модель вообще "не знает" о триаде и может использоваться отдельно, вне контекста триады или компонента. Методы Модели могут работать с переменными состояния, значения которым было присвоено ранее (обычно Контроллером), могут изменять значения этих переменных или выдавать их по запросу. Модель никогда не должна получать данные напрямую или обращаться к конкретному Контроллеру или Виду. Модели независимы ни от чего, в этом их сила.

На схеме непосредственно под Моделью расположен небольшой блок, названный Таблица. Это странный "зверь". Он и адаптер для подключения к базе данных, и модель, и контроллер, но не является ничем из перечисленного на 100%. Таблица используется для создания объекта из одной записи в базе данных. Она обычно проверят валидность записи перед её сохранением в базе данных или преобразует данные после их чтения из базы данных (например, десериализовать данные в JSON-формат).

Последняя часть триады - это собственно Вид. Он запрашивает у Модели исходные данные и преобразует их в подходящее представление. Чаще всего - это получение от Модели записей из базы данных и их последующее преобразование в HTML. Но это не единственный вариант использования Вида - он может преобразовывать данные в JSON или CSV формат, может создавать графический, аудио или видео-файл. Именно Вид преобразует исходные данные во что-то удобочитаемое. Чаще всего это делается загрузкой php-файлов шаблона. Если используется описание форм в XML, Вид запросит у Модели описание формы, затем передаст их в Генератор форм (включённый в состав FOF, но не показанный на схеме), Генератор в свою очередь вернёт в Вид форму в HTML-виде. Несмотря на то, что функция сборки формы передана в Генератор форм, за итоговое представление данных отвечает Вид, именно Вид возвращает сформированные данные запрашивавшему их Контроллеру. Хотим ещё раз подчеркнуть, что Вид "не знает" ни про Контроллер, ни про Модель, с которыми работает. Правильно написанный Вид полностью независим от остальных частей компонента и будет работать с любым источником данных при условии сохранения интерфейса, а также с любым потребителем этих данных.

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

Есть ещё один элемент на схеме, расположенный под триадой - Панель инструментов. Панель инструментов концептуально связан с компонентом и отображается в сформированных HTML-страницах. В Панель инструментов входит отображение названия в административной части, кнопки управления в пользовательской и административной частях сайта, навигация и меню в административной части. Если вы не заметили, F0FToobar позволяет отображать кнопки управления в пользовательской части сайта, чего так не хватало в оригинальной Joomla!. Для этого будет достаточно добавить несколько CSS-классов.