Толстые модели и тощие контроллеры звучат как создание моделей Бога [закрыто]

91

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

  1. Контроллер и маршрутизатор на самом деле не выполняют много разных задач, кроме простого вызова метода в богоподобной модели на основе маршрута.
  2. Модели слишком много делают. Отправка электронных писем, создание отношений, удаление и изменение других моделей, постановка задач в очередь и т. Д. По сути, теперь у вас есть богоподобные объекты, которые должны делать все, что может или не может иметь отношение к моделированию и работе с данными.

Где вы проводите линию? Разве это не соответствует образцу Бога?

Охотник за джунглями
источник

Ответы:

137

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

Немного теории

Люди, дающие такой совет, похоже, подвержены довольно распространенному заблуждению. Итак, позвольте мне начать с разъяснения: модель в современном шаблоне проектирования MVC НЕ является классом или объектом. Модель - это слой.

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

Основные части, из которых состоит слой модели:

  • Объекты домена

    Также известны как объекты домена, бизнес-объекты или объекты модели (мне не нравится это последнее название, потому что оно только добавляет путаницы). Эти структуры обычно ошибочно называют «моделями». Они отвечают за содержание бизнес-правил (всю математику и проверку для конкретной единицы логики домена).

  • Абстракции хранения:

    Обычно реализуется с использованием шаблона отображения данных (не путать с ORM , которые злоупотребляют этим именем). Этим экземплярам обычно поручается хранение и извлечение информации из объектов домена. Каждый объект домена может иметь несколько сопоставителей, так же как существует несколько форм хранения (БД, кеш, сеанс, файлы cookie, / dev / null).

  • Сервисы:

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

Между этими группами может быть несколько структур: DAO , единицы работы и репозитории .

Ох ... и когда мы говорим (в контексте сети) о пользователе который взаимодействует с приложением MVC, это не человек. «Пользователь» - это на самом деле ваш веб-браузер.

Так что насчет божеств?

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

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

Каждая служба может взаимодействовать с любым количеством (хотя обычно это всего лишь несколько) абстракций объекта домена и хранилища. Например, они RecogitionServiceне могут меньше заботиться об абстракциях хранения статей.

Заключительные примечания

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

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

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

терешко
источник
Очень полезный и полный ответ! Знаете ли вы какую-нибудь книгу, которая более подробно объясняет архитектурный паттерн MVC? Особенно в части моделей, которую все ошибочно думают: «Модель представляет данные и больше ничего не делает». и это больше похоже на идею объекта домена, а не на «Модель» -> tomdalling.com/blog/software-design/…
thermz
1
@thermz, AFAIK , там действительно нет книг , которые имеют дело исключительно с MVC шаблон. Обычно я просто говорю людям прочитать PoEAA , а потом копать. Может быть, этот список ссылок будет полезен. Я считаю, что, когда люди хорошо разбираются в принципах и концепциях ООП, этот шаблон становится довольно легко понять.
tereško
@ tereško красивый ответ. Достигает ли этого Hibernate? Я не уверен в ответах здесь -> stackoverflow.com/questions/1308096/…
Ankan-Zerob
@ Ankan-Zerob, как вы могли заметить, я не являюсь разработчиком Java, но из того, что я знаю о Hibernate, он предоставляет полный набор инструментов для уровня сохраняемости. Это даст вам часть того, что там описано, но не полный слой модели.
tereško
3
@johnny, насколько мне известно. Большинство так называемых «фреймворков mvc» php являются вариациями Rails. И, как часть курса, большинство из них поставляются с некоторыми активными решениями ORM на основе записей (эти вещи, как известно, уязвимы для изменений в БД). Вы можете реализовать что-то подобное с SF2.x или ZF2.x, но суть фреймворка не в том, чтобы реализовать / обеспечить конкретную архитектуру, а в предоставлении инструментов. Кроме того, когда дело доходит до MVC, он реализуется кодом приложения, а не фреймворком.
tereško
5

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

Настоящий вопрос в том, что подразумевает модель в MVC. Он не ограничивается классами POCO несколькими методами. Модель в MVC означает данные и бизнес-логику. Рассматривайте его как надмножество классических основных моделей POCO.

Просмотр ==== Контроллер ==== Модель ---> Уровень бизнес-процессов -> Основные модели

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

BPL может вызывать шаблоны UoW / репозитория, выполнять бизнес-правила и вызывать функции инфраструктуры посредством внедренных объектов или шаблонов интерфейса.

Таким образом, рекомендация держать контроллер "тонким" не означает, что класс "person" в классической модели Core должен иметь 50 методов и напрямую вызывать Email. Вы правы, думая, что это неправильно.

Контроллер может по-прежнему потребоваться для создания экземпляров и внедрения классов инфраструктуры в BPL или базовый уровень, если вызывается напрямую. Должен быть бизнес-уровень или, по крайней мере, классы, управляющие вызовами через классы классической объектной модели. В любом случае, это моя "точка зрения" ;-)

Для общего использования MVC описание вики http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Небольшой блог, в котором рассказывается о букве "M" в MVC. http://www.thedeveloperday.com/skinny-controllers/

Фил Соеди
источник
1
Если вы не согласны, по крайней мере, будьте достаточно вежливы, чтобы оправдать свое мнение
Фил Соади
-1

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

Брайан Янг
источник