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

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

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

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

3 ответа

Решение

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

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

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

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

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

  • Доменные объекты

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

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

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

  • Сервисы:

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

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

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

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

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

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

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

Закрытие заметки

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

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

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

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

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

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

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

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

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

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

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

Небольшой блог, рассказывающий о "М" в MVC. http://www.thedeveloperday.com/skinny-controllers/

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

Другие вопросы по тегам