Понимание MVC: что такое понятие "жир" на моделях, "тощий" на контроллерах?

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

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

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

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

OBS3:" checkIfEmailExists ()", это не просто контроллер ? Он на самом деле не выполняет какую-то дрянь, он просто сравнивает ценности и т. д. Вот что меня смущает, потому что в моей голове это контроллер: S

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

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

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

заключительное Примечание: обсуждение закончилось, сказав, что я ошибаюсь, желание в порядке (я учусь). Но, Итак, какие правильные ответы для Q2 и Q3 ?

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

5 ответов


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

Если у вас есть контроллер fat, например, полный бизнес-логики, вы не придерживаетесь цели 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');
    }
}

, когда он должен быть!--3-->

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, см. Мой ответ на могу ли я вызвать модель из вида.


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

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

часть "контроллер" - это то, что заботится о веб-конкретных вещах, таких как аутентификация, cookies, GETs и POSTs, querystrings и т. д. Он использует материал, присутствующий в модели и / или BLL, и отправляет данные, которые должны быть переданы пользователю в представления.

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

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


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

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


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

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


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

хорошим примером этого разделения является:

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