Понимание MVC: что такое понятие «жир» на моделях, «тощий» на контроллерах? - PullRequest
21 голосов
/ 24 июня 2010

Я пытаюсь понять концепцию "жира" на моделях против "тощего" на контроллерах, и из того, что я обсуждал, у меня есть следующий пример (это взято из обсуждения freenode):

В: О парадигме MVC, ее моделях Fat, тощих контроллерах.Я здесь думаю: если у меня есть много методов (на контроллере), которые используют только несколько абстрактных методов для CRUD (на модели), я создаю толстый контроллер вместо модели?Или, говорят, толстая модель, повторяющаяся в том, что возвращается, а не набирается?это то, чего я никогда не понимал =) Любые комментарии приветствуются!Большое спасибо

OBS1: я не делаю что-то с помощью модели, в контроллере, у меня просто есть методы, которые управляют тем, что происходит с моделью

OBS2: скажем, "checkIfEmailExists () ", имеет" john@hotmail.com ", в качестве параметров.Этот метод получит возврат из метода модели, который запрашивает, существует ли этот параметр в таблице, и возвращает логическое значение.Если равно 0, «checkIFemailExists ()» вызовет метод другой модели, этот, он просто еще один абстрактный метод, который выполняет операцию обновления.

OBS3: «checkIfEmailExists ()», это не просто контроллер?На самом деле он не выполняет CRUD, он просто сравнивает значения и т. Д. Это меня смущает, потому что в моей голове это контроллер: S

Примечания: я думаю, что это не лучший пример, так как я говорю «проверьте, есличто-то существует ", звучит как запрос, моя табличная операция

Q2: еще один вопрос, так что, скажем, у меня есть форма просмотра, откуда этот параметр адреса электронной почты отправляется.Вы хотите сказать, что представление идет непосредственно к модели?

Q3: Разве контроллер не должен действовать между ними?Вот парадигма

ЗАКЛЮЧИТЕЛЬНОЕ ПРИМЕЧАНИЕ: обсуждение закончилось, сказав, что я ошибаюсь, желание в порядке (я учусь).Но так, каковы правильные ответы для Q2 и Q3?

Спасибо за ваше внимание

Ответы [ 5 ]

34 голосов
/ 24 июня 2010

Ваше приложение - это M. Оно должно быть в состоянии стоять независимо от V и C. V и C образуют пользовательский интерфейс для вашего приложения.Является ли это веб-интерфейсом или интерфейсом командной строки, не должно иметь значения для запуска основной бизнес-логики вашего приложения.Вы хотите, чтобы модель была насыщенной бизнес-логикой.

Если у вас вместо этого толстый контроллер, например, полный бизнес-логики, вы не придерживаетесь цели MVC.Единственная ответственность контроллера заключается в обработке и делегировании запросов пользовательского интерфейса к Модели.Вот почему это должно быть тощим.Он должен содержать только код, необходимый для того, за что он отвечает.

Упрощенный пример

public function fooAction()
{
    if(isset($_POST['bar'])) {
        $bar = Sanitizer::sanitize($_POST['bar']);
        $rows = $this->database->query('SELECT * from table');
        try {
            foreach($rows as $row) {
                $row->foo = $bar;
                $row->save();
            }
        } catch (Exception $e) {
            $this->render('errorPage');
            exit;
        }
        $this->render('successPage');
    } else {
        $this->render('fooPage');
    }
}

Когда это должно быть

public function fooAction()
{
    if(isset($_POST['bar'])) {
        $success = $this->tableGateway->updateFoo($_GET['bar']);
        $page    = $success ? 'successPage' : 'errorPage';
        $this->render($page);
    } else {
        $this->render('fooPage');
    }
}

, потому что это все, что контроллер должен знать,Не следует обновлять строки.Следует просто сообщить модели, что кто-то запросил это изменение.Обновление является обязанностью класса, управляющего строками.Кроме того, контроллер не обязательно должен очищать значение.

Что касается Q2 и Q3, см. Мой ответ на Могу ли я вызвать модель из представления .

8 голосов
/ 24 июня 2010

Я давно работаю с парадигмой MVC и могу поделиться с вами своим опытом.

Часть "модель" отвечает за обработку всего, что не является строго "веб"такие как проверка, логика, доступ к данным и т. д. Думайте о нем как о смешанном бизнес-уровне + уровне доступа к данным.Вы также можете использовать BLL + DAL в отдельных сборках и использовать часть «Модель» в MVC в качестве моста между вашей BLL и вашим приложением, а также добавлять классы, специфичные для приложения MVC и не связанные с BLL, например классы ViewData.и т. д.

«Контроллер» - это то, что заботится о вещах, специфичных для сети, таких как аутентификация, куки, GET и POST, строки запросов и т. д. Он использует материал, присутствующий в модели и / или BLLи отправляет данные, которые должны быть представлены пользователю, в представления.

«Представления» - это ваши HTML-шаблоны, которые могут получать данные от контроллера и отображать их.Никакие логические операции никогда не должны выполняться в представлениях, поэтому нет операторов if, циклов и т. Д. Если вы обнаружите, что у вас есть такие потребности, то вам нужны некоторые вспомогательные методы, которые создают желаемый HTML и затем вызывают их изПосмотреть.Таким образом, представления только получают данные и предлагают пользователям ссылки / формы для публикации данных на контроллере, но они ничего не уточняют.

Надеюсь, это сняло некоторые ваши сомнения.

3 голосов
/ 24 июня 2010

Я всегда интерпретировал это как означающее, что модели должны инкапсулировать логику, связанную с этими моделями, в более объектно-ориентированном подходе, в отличие от наличия всей логики в контроллерах в более процедурном подходе. Цитировать Кафедральный собор и базар :

Умные структуры данных и тупой код работают намного лучше, чем наоборот.

2 голосов
/ 24 июня 2010

Я могу показывать свою предвзятость (по отношению к C #), но я не думаю, что имеет смысл говорить о MVC, если вы не используете стиль объектно-ориентированного программирования.Контроллер - это не метод, это набор методов, сгруппированных в класс, каждый из которых обрабатывает некоторый ввод (url / request).Модель - это не способ доступа к базе данных (это слой доступа к данным), это совокупность свойств и методов, которые инкапсулируют некоторую идентифицируемую сущность в вашем приложении: личность, резервирование, продукт и т. Д. Лучший способдумать о том, что контроллеры обрабатывают ввод, модели содержат данные - но, конечно, это упрощено.

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

0 голосов
/ 24 июня 2010

Я думаю, что хорошее разделение контроллер / модель может быть достигнуто, если позволить контроллеру выполнять «синтаксические» зависимые операции без задействованной бизнес-логики или без нее и использовать модель для выполнения «семантических» связанных операций.

Хороший пример такого разделения:

вы можете выполнить проверку регулярного выражения для электронной почты в контроллере, но вы не будете выполнять сопоставление ldap этого сообщения в контроллере.

...