Должен ли контроллер знать о представлении и модели? или наоборот?

13

Я концептуально пытаюсь понять, должен ли я делать это:

item = Model()
screen = View()
brain = Controller(item, screen)

или это..

brain = Controller()
item = Model(brain)
screen = View(brain)

или это..

class Controller():
    def __init__(self):
        item = Model(self)
        screen = View(self)

или что-то еще целиком?

alnafie
источник

Ответы:

18

Для меня первый вариант имеет смысл. Работа контроллера заключается в координации между представлением и моделью. С этой точки зрения для контроллера имеет смысл быть тем, кто управляет ссылками на представление и модель.

Вы не можете иметь контроллер без Модели и Представления, однако гораздо разумнее просто иметь Представление или просто Модель (например, в модульном тестировании). Вот почему вы хотите передать эти зависимости в контроллер, а не в две другие.

Oleksi
источник
9

ModelИ Viewнезависимы друг от друга.

Не думайте об этом Controllerкак о мозгах структуры MVC. Думайте об этом как о диспетчере, который обрабатывает запросы от браузера и отправляет их в Model. Затем он берет данные из Modelи упаковывает их в виде шаблона , а затем отправляет их в View.

ModelЯвляется мозг в структуре MVC, и это, где вы должны положить ваши бизнес - правила. Бизнес-правила являются общими для нескольких контроллеров . Таким образом, контроллер документа и контроллер отчетов могут использовать модель пользователя, чтобы увидеть, кто имеет доступ к этим вещам. Вы не хотели бы повторять эти правила в обоих контроллерах.

ViewСледует использовать шаблон HTML , чтобы представить данные определенным образом без источника данных. Он не должен быть тесно связан со схемой вашей базы данных. Чтобы показать заголовок документа, у вас должно быть представление, выводящее содержимое переменной шаблона с именем document_title, и только Controllerзнает, как была установлена ​​эта переменная, и только Modelзнает, почему этот документ имеет этот заголовок.

Reactgular
источник
1
Мне нравится ваш ответ, поскольку он гармонирует с моим общим пониманием MVC. Тем не менее, он не затрагивает важную часть вопроса, в частности, какие части Триады содержат ссылки на другие? Я полагаю, что путаница связана с тем, что вы описываете, что представления являются «тупыми шаблонами с дырами» (т. Е. Не содержат ссылок на контроллер, но контроллер знает представления и вставляет в них данные модели). В то же время, еще одна распространенная вещь, которую я продолжаю видеть, это то, что Views должен посылать действия пользователя в контроллер. Как в Views могут сделать это, не имея ссылки на C?
alnafie
@alnafie Вы упростили структуру MVC всего за 3 класса. Взгляните на существующие платформы с открытым исходным кодом MVC, и вы обнаружите, что для его работы требуется гораздо больше. Должно быть что-то более высокое, что управляет всеми частями фреймворка. То, что вызывает контроллеры, и то, что обрабатывает маршрутизацию к действиям в представлениях.
Reactgular
3

Первоначально MVC был определен для облегчения программирования настольных приложений. Представление подписывалось на события модели, обновляя представление при изменении модели. Контроллер просто переводил события пользовательского интерфейса (например, нажатие кнопки) в вызовы модели. Таким образом, контроллер и вид зависят от модели, но не зависят друг от друга. Модель не зависит от обоих. Это позволило нескольким представлениям и контроллерам работать на одной модели.

Архитектура "MVC", используемая для приложений web 1.0 (полное обновление страницы, без AJAX), несколько отличается. Веб-запрос отправляется на контроллер. Контроллер каким-то образом изменяет состояние модели, а затем отправляет одну или несколько моделей для визуализации представлением. Контроллер и вид зависят от модели, но контроллер также зависит от вида.

С приложениями web 2.0 мы возвращаемся к классической архитектуре MVC на стороне клиента . Модель, представление и контроллер находятся на стороне клиента как объекты Javascript. Контроллер переводит пользовательские события в действия модели. Действия модели могут приводить или не приводить к запросу AJAX на сервер. Опять же, представление подписывается на события модели и соответственно обновляет презентацию.

Кевин Клайн
источник
+1 хороший ответ. Я могу понять модели обратных вызовов для настольных приложений в классическом смысле. Напоминает мне старый MFC от Microsoft.
Reactgular
2

Представление должно подписываться на изменения в модели. Существует богатство подписок, поскольку они могут быть подробными (показать изменения инвентаря для этого конкретного элемента) или общими (модель изменилась); представление может запросить модель в ответ на уведомление об изменении. Представление представляет желаемый набор элементов модели на экране, обновляя экран, как при обработке уведомлений об изменениях.

Контроллер должен выдвигать изменения в модели в зависимости от направления пользователя (например, ввод клавиатуры, команды мыши и меню).

Модель поддерживает модель и список подписок и должна уведомлять представления о применимых изменениях через свои подписки.

Также должен быть механизм для создания новых представлений и контроллеров (поскольку в MVC вы должны иметь возможность иметь два или более представлений одной и той же модели (это могут быть одинаковые представления (точки) или разные представления (точки)). Логически мы можем считать, что контроллер должен работать или иметь доступ к фабрике представления и контроллера (пары), которая может быть частью контроллера или другого компонента.

Эрик Эйдт
источник
-1 Modelsне сообщай Views. Controllersзапросите Modelизменения, а затем Viewsвыполните рендеринг, чтобы представить эти изменения.
Reactgular
4
@MathewFoscarini в MVC, представление подписывается на изменения из модели. Смотрите, например, wiki.squeak.org/squeak/598 .
Я думаю, что мы не говорим о различиях в существующих платформах MVC. Zend MVC, C # .NET и CakePHP не подключают модель к представлению. Представление в этих рамках является независимым. Я не знаю, с каким MVC вы работали, но я бы назвал это нетрадиционным.
Reactgular
6
@MathewFoscarini: это все веб-фреймворки, и хотя они называют себя «MVC», они не следуют классической архитектуре MVC.
Кевин Клайн
2
Я не уверен, что какой-либо MVC является более «традиционным», чем Smalltalk MVC, так как он был первым, где был описан шаблон.
1

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

Чтобы добиться этого, шаблон должен изолировать логику реализации каждого компонента MVC. Тем не менее, совершенно нормально, что компоненты знают интерфейсы друг друга .

Что я часто видел, так это то, что контроллер создает или вызывает модель и представление (таким образом, он знает их интерфейс), а модель или представление могут уведомлять контроллер в ответ (больше похоже на обратный вызов или шаблон наблюдателя). Важной частью является то, что контроллер не знает о структуре макета.

Марк-Эммануэль Купе де Гра
источник