Модель и паттерн MVC (Model-View-Controller)
|
Опубликовано: 11.12.2008
|
Неделю назад известный в кругах Zend Framework сообщества девелопер Pádraic Brady написал замечательную статью о понятии Модели в паттерне MVC. С полным текстом вы можете ознакомиться по ссылке.
Что же поведал нам Pádraic. Далее, мой очень вольный и краткий перевод.
Оказывается, много программистов понимают модель не совсем корректно, бытует мнение, что концепция модели идентична концепции доступа к данным. На самом деле эти понятия связаны, но не идентичны. Модель можно определить исходя из следующих положений:
1. Модель отвечает за сохранение состояния приложения между HTTP запросами
Любые данные, храняться ли они в базе, в файле в сессии, или закешированы внутри APC должны быть сохранены между запросами. Помните модель это не только база данных, даже данные полученные от веб сервисов можно интерпретировать как модель, даже Atom фиды.
2. Модель включает все правила, ограничения и поведения, используемые для управления и работы с информацией
На практике это означает что любой функционал тем или иным образом оперирующий с состоянием вашего приложения, то есть вашими данными это модель. Такая модель называется толстой (fat model)
Вид должен позаботиться о генерации и отображении пользовательского интерфейса. Контроллеры же выступают в роли посредника, что получает данные от пользователя, транслирует их в модель и отдает результат Виду. Более в контроллерах не должно быть ничего. Кода в контроллерах должно быть минимальное количество.
Хорошее MVC приложение должно исходить из вышеизложенных принципов. На практике же произошло по другому, многие разработчики стали понимать модель как «общий» термин обозначающий работу с базой данных.
И что же получилось в итоге, разработчики придумали новую концепцию. ТТУК - Толстые тупые уродливые контроллеры (Fat Stupid Ugly Controllers, так назвал ее Pádraic :)). Среднестатистический ТТУК получал данные из БД (используя уровень абстракции базы данных, делая вид, что это модель) или манипулировал, валидировал, записывал, а также передавал данные в Вид. Такой подход стал очень популярен, потому что использование таких контроллеров похоже на классическую практику использования отдельного php файла для каждой страницы приложения.
Заметили что-то странное? Контроллеры стали выполнять практически всю работу с данными, ведь если эту работу не выполняет Модель – она должна сместиться в Контроллер. Итак, мы получили Контроллер - Модель мутант. А это в корне не правильно, такой толстый контроллер практически не передается переносу и тестированию (TDD). Ведь мы не можем создать экземпляр класса контроллера вне фреймворка, контроллер жестко привязан к определенному фреймворку. Модель же должна исповедовать принцип «подключил и работает». Например, вы можете взять модель, написанную для Zend Framework и перенести ее на Symfony, и это не будет очень сложной задачей. А тестирование! Ведь нам придется прогнать весь цикл работы фреймворка что бы оттестировать только один контроллер.
Большая часть фреймворков заявляет что они дают нам все три составляющие MVC архитектуры, на самом деле это не совсем так. Модель это нечто что мы должны реализовать сами, Модель по сути и является ядром нашего приложения, именно Модель это то о чем мы общаемся с заказчиками. И модель не должна быть сильно зависима от фреймворка.
По сути все MVC фреймворки можно было бы назвать VC фреймворки, но тут в дело вмешиваются торговцы и маркетологи, кто захочет что бы его фреймворк остался без буквы M. Таким образом фреймворки косвенно поощряют мнение о том что модель это что-то сродни уровня абстракции базы данных которые поставляются с фреймворком, например Zend_Db. Модель от этого становится худой и бедной.
Мое мнение, что Вид вообще должен по возможности избегать контакта с Контроллером и получать данные напрямую из модели. В Zend Framework это можно делать с помощью помощников вида. Самый лучший контроллер это пустой контроллер!
Конец перевода. Далее от своего лица.
Подведу итог, Pádraic настойчиво убеждает минимизировать функциональность контроллеров, перенеся ее в модели. сделав контроллеры худыми, а модели толстыми. Более того в комментариях к статье Matthew Weier O'Phinney поддержал автора и добавил что сам он был против введения в Zend Framework такого помощника вида как action. На первый взгляд этот помощник является очень удобным, например, так можно построить меню, или вывести блок последние новости. Но по сути своей этот помощник раздувает наши контроллеры, эти лишние обращения к действиям не обоснованны, более того использование помощника сильно сказывается на производительности. При вызове action() клонируется объекты запроса и ответа, вызывается контроллер и действие итд.
Помощники вида, что обращаются напрямую к модели, дают возможность избавиться от использования action(). Пример такого помощника вы можете увидеть здесь
И напоследок напутствие от Pádraic:
«Думайте товарищи, желание думать должно быть основным, спрашивайте везде, анализируйте, протестуйте, когда что-то вам кажется не разумным. Если вы все принимаете на чистую веру, значит вы заслуживаете того что получаете.»
Вот так вот, отличное напутствие новичкам, которые часто забывают что у них своя голова не плечах. Всем новичкам рекомендую прочтение оригинала статьи, он более комплексный и убедительный чем мой краткий перевод.
А что вы думаете о модели?

