MVC (Model View Controller) с инкапсуляцией / защитным программированием - PullRequest
0 голосов
/ 01 ноября 2018

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

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

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

Я спросил об этом своего профессора и указал на некоторые нарушения в абстракции и инкапсуляции с MVC, и он ответил, что «это часть проекта, чтобы ответственно использовать ссылки на представление и модель. Если кто-то разрабатывает модель случается воспользоваться отсутствием инкапсуляции представления, тогда это нарушает контракт дизайна. "

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

Ответы [ 3 ]

0 голосов
/ 04 ноября 2018

Объекты модели - это не глупые данные, это настоящие объекты с поведением. Таким образом, контроллер не может аннулировать данные модели, как вы сказали. Работа контроллера - это просто преобразование входных данных, отправленных из View, в формат, который можно понять по поведению, представленному Model. Если преобразование завершится успешно, контроллер передаст преобразованный вход в модель. В противном случае, контроллер будет напрямую уведомлять о просмотре, не беспокоясь о модели.

Модель также не может напрямую изменять вид, как вы сказали. Модель сохраняет косвенную ссылку на View: Модель не зависит от типа View, но зависит от интерфейса, реализуемого View. Модель просто замечает вывод в View. Как View реагирует (как удаление сцены) на полученный вывод, зависит от View.

Позволять объектам напрямую изменять данные других объектов - очень плохая практика в ООП.

0 голосов
/ 04 ноября 2018

Думайте об этом как о двух отдельных приложениях:

Контроллеры живут в одном приложении. Их цель - принимать входные данные и / или создавать выходные данные. И вход, и выход - это Модель, часто одна и та же (после небольшой проверки). Модели - просто тупые контейнеры для входов и выходов.

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

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

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

0 голосов
/ 02 ноября 2018

Когда я реализую MVC, Модель не имеет доступа ни к Контроллеру, ни к Представлению. На самом деле, я пытаюсь ограничить модель просто необработанными данными - например, копией записи из базы данных. Простой, легкий.

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

Представление не имеет прямого взаимодействия с моделью. Он обновляется в ответ на события из контроллера. Взаимодействия с пользователем (например, редактирование текстового поля, нажатие кнопки и т. Д.) Обычно перенаправляются на контроллер. Уровень пользовательского интерфейса должен заботиться только о работе с пользовательским интерфейсом.

Таким образом, у вас есть приятная многоуровневая программная архитектура: UI -> Business Logic -> Data. Ничто не может напрямую взаимодействовать со слоем поверх него - разрешены только косвенные взаимодействия через события. Вы также можете передавать один и тот же экземпляр контроллера нескольким представлениям, чтобы они оставались синхронизированными.

...