Что конкретно относится к модели, представлению и контроллеру?

Я изучал парадигму модель-представление-контроллер («MVC»), но я очень запутался, поскольку некоторые учебники противоречат другим учебникам.

Мое текущее понимание процесса выглядит примерно так:

Маршрутизатор / Диспетчер / Фронт-контроллер:

  • Маршрутизатор, хотя и не упоминается в названии MVC, по-прежнему является очень важной частью. Именно здесь запросы переводятся из необработанных URL-адресов на конкретный контроллер. Например, маршрутизация запроса на www.StackUnderflow.com/question/123 к контроллеру вопросов приложения.

Модель:

  • Здесь необработанные данные собираются из некоторого источника хранения, такого как база данных или XML-файл. Модель служит уровнем абстракции, преобразуя запрос Контроллера для определенных данных в (например) запрос SQL и преобразуя результаты запроса в стандартный формат, такой как объект данных.

  • Например, в сценарии / browse / all, указанном выше:

    • The "Question" Controller would ask the Model "Please give the data for question 123."
    • Затем Модель преобразует это в «ВЫБРАТЬ * ИЗ ВОПРОСОВ, ГДЕ Id = 123;» и перенести его в базу данных
    • База данных вернет в Модель запись «Вопрос».
    • Модель возьмет запись и переведет ее в объект данных вопрос.
    • Затем модель просит сделать то же самое: «SELECT * FROM Answers WHERE QuestionID = 123;» и создает массив объектов Answer из набора результатов и добавляет его к переменной-члену answers объекта Question.
    • Модель вернет объект "Вопрос" в Контроллер "Вопрос".

Контроллер:

  • Это настоящая рабочая лошадка приложения. Помимо ретрансляции сообщений в Модель и Представление, Контроллер также отвечает за такие вещи, как авторизация и приложение / "бизнес-логика" Изменить: Согласно ответу, бизнес-логика принадлежит модели.

  • В текущем примере Контроллер будет отвечать за:

    • Ensuring the user is logged in.
    • Определение QuestionId из URL-адреса.
    • Определение того, какой вид использовать.
    • Отправка кодов HTTP и перенаправление при необходимости.
    • Запрос данных у модели и сохранение необходимых данных в переменных-членах.

Вид:

  • По большому счету, View - это самая простая часть приложения. В основном это базовое приложение, состоящее из HTML-шаблонов. Эти шаблоны будут иметь заполнители для вставки данных в шаблон из переменных-членов контроллера:

e.g.

<html>

  <head>
    <title>
      <?php $question->getTitle() ?>
    </title>
  </head>

  <body>
    <h1> <?php $question->getQuestionText(); ?> </h1>
    <h2> Answers: </h2>
    <div class="answerList"> 
      <?php formatAnswerList($question->getAnswers()); ?> 
    </div>
  </body>

</html>
  • Представление также будет содержать методы форматирования данных для доставки пользователю. Например, приведенный выше метод formatAnswerList() будет принимать массив ответов, взятых из Контроллера, и перебирать их в цикле, вызывая что-то вроде include $markupPath . "/formatAnswer.inc", которое будет небольшим шаблоном просто контейнера ответа.

Вопросы:

  • Насколько точен этот взгляд на MVC?
  • Если нет, пожалуйста, внимательно объясните, какие компоненты неуместны, где они должны быть на самом деле и как они должны правильно взаимодействовать с другими компонентами (если вообще).
  • Сколько классов используется для описания этого? В моем примере есть четыре объекта - по одному для трех компонентов MVC и один, который просто хранит связанные данные для передачи. Это нормально, или нужно комбинировать некоторые из них. Если да, то какие?

person AgentConundrum    schedule 23.08.2010    source источник


Ответы (2)


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

Понимание MVC: что такое концепция Fat на моделях, на контроллерах Skinny?

person David    schedule 23.08.2010
comment
Думаю, я понимаю, к чему вы клоните. Многое из того, что у меня есть в контроллере, на самом деле является частью модели, и уровень абстракции, который у меня есть в модели, вероятно, больше представляет собой отдельный объект (возможно, считается подмножеством модели), а не цель модели. что правильно? Не могли бы вы обновить свой ответ, чтобы указать, какие части моего Контроллера должны остаться, а какие - в Модель? Кроме того, должны ли все классы M, V и C быть отдельными классами или они должны быть каким-то образом объединены. Если да, то какие части входят в какие классы? Спасибо. - person AgentConundrum; 23.08.2010
comment
Честно говоря, ваш пример уже довольно хорош. В основном я отмечал комментарий рабочей лошадки к контроллеру. Возможно, это рабочая лошадка пользовательского интерфейса, хотя многое можно сделать в логике представления, но модель - это рабочая лошадка предметной области. Как и в другом ответе, важно отметить, что сущность вопроса (запись, как вы ее назвали) и DTO вопроса (объект, как вы ее назвали) являются отдельными. Одно должно быть изменяемым, не влияя на другое. - person David; 23.08.2010
comment
@David: Читая ответ Джайлза, я понял, что, возможно, запутал классы, хотя думал, что из контекста можно сделать вывод о том, что я имел в виду. Что касается объектов Вопроса, я видел четыре в этом примере. QuestionM (модель), QuestionV (представление), QuestionC (контроллер) и старый добрый вопрос, который служил в основном для инкапсуляции данных - я полагаю, он мог бы быть массивом, а не объектом. - person AgentConundrum; 23.08.2010
comment
@David: Точнее говоря, есть ли примеры, которые я использовал в Контроллере, которые ему не принадлежат? Я думаю, что все там ограничивалось либо описанием состояния (и QuestionC, насколько я понимаю, также отвечает за запоминание состояния), либо передачей информации в / из представления или модели. Должна ли часть кода HTTP (или фактически что-либо связанное с HTML, например метатеги, такие как ключевые слова или заголовок страницы) быть частью представления, или они в порядке в контроллере? Используемый пример очень ориентирован на CRUD, и я не хочу запутаться: значит, вы говорите, что вся тяжелая работа - это модель? - person AgentConundrum; 23.08.2010
comment
@AgentConundrum: Нет, я думаю, что примеры контроллера в вопросе довольно точны. Естественно, в поле зрения должно быть как можно больше презентации. Но всегда есть вещи, связанные с презентацией, которые должны выполняться контроллером, как в приведенных вами примерах. Для моих сайтов, вероятно, наиболее распространенной частью логики в контроллере является авторизация по действию. На основе текущего токена аутентификации он проверяет роли и разрешает или отклоняет действие на основе этого. - person David; 23.08.2010
comment
@ Дэвид: Отлично. Думаю, я действительно начинаю это понимать. Пожалуйста, примите этот бонус «Принятый ответ» в знак моей признательности. :) - person AgentConundrum; 23.08.2010
comment
@AgentConundrum: Ой, я действительно надеялся на принятый ответ с нулевым баллом. Я довольно близок к значку «Невоспетый герой». Я не знаю, будет ли отмена голосования постфактум иметь такой же эффект, так что с таким же успехом можно оставить голосование :) - person David; 23.08.2010
comment
@ Дэвид: Я только что попытался отменить голосование, но поскольку с момента голосования прошло два часа, голосование заблокировано. Если вы отредактируете ответ (что-то тривиальное), я отзову голосование и посмотрю, поможет ли это. Если нет, я откажусь от ответа и посмотрю, даст ли вам значок, если я снова приму его при 0 голосах. Было бы неплохо подарить кому-нибудь золотой значок, но я не думаю, что Unsung Hero так же просто, как принятие с нулевым количеством голосов - проверьте некоторых людей, у которых они есть, и вы поймете, что я имею в виду. Также указано, что количество принятых ответов нулевое: более 10 и 25% от общего числа. Не знаю, что означает последняя часть ... - person AgentConundrum; 23.08.2010
comment
@AgentConundrum: Я ценю это, но не беспокойтесь об этом. Насколько я могу судить, все, что мне нужно, это в общей сложности 11 принятых ответов с нулевым баллом (более 10), прежде чем я получу в общей сложности 44 принятых ответа (25%). У меня осталось 4. Это так просто, обратите внимание на значок Tenacious, на котором у меня было 6 нулевых баллов (более 5), прежде чем у меня было 30 баллов (20%). - person David; 23.08.2010

По сути, у вас все в нужном месте.

В вашем примере вы определяете класс вопроса, который будет известен как ViewModel, просто контейнер для всех данных, которые будут использоваться в представлении / извлечены из представления.

В некоторых случаях я видел, как ViewModel упускается из виду, а модель передается в View - это меня смутило, когда я впервые смотрел учебные пособия, и мне не нравится пропускать ViewModel, я думаю, что это сбивает с толку.

person Giles Smith    schedule 23.08.2010
comment
Является ли ваша ViewModel моим контроллером или я запутался? Я смотрел на шаблон как на три отдельных объекта (поэтому в моем представлении был указан $ question, а не $ self). С учетом того, что вы говорите о игнорировании ViewModel, разве это будет похоже на отсутствие контроллера, когда модель и представление просто общаются друг с другом? - person AgentConundrum; 23.08.2010
comment
Думайте о модели как о вашем фактическом домене объектов и логики, о модели представления как о простом POCO DTO, который передает данные в представление, а о контроллере как об операторе коммутатора, который передает информацию (и обрабатывает любые связанные с пользовательским интерфейсом вещи, такие как состояние сеанса). , которые не входят в модель. - person David; 23.08.2010
comment
@David: Хорошо, поэтому ViewModel - это просто то, что вы называете объектом, используемым для хранения данных только для передачи / хранения, Модель предназначена для работы с данными, Контроллер предназначен для хранения данных / состояния и передачи данных между моделью ‹- ›View, а View - только для рендеринга HTML? Это по сути правильно? - person AgentConundrum; 23.08.2010
comment
@AgentConundrum: Кажется, правильно. Модель может быть довольно сложной. Для большинства моих сайтов бизнес-логика находится за уровнем сервиса, а Модель - это, по сути, просто взаимодействие с сервисом. В этом случае это оказывается более процедурным, чем мне хотелось бы, но это то, что есть. - person David; 23.08.2010