Толстая модель/тонкий контроллер против уровня обслуживания

Я много лет разрабатываю корпоративные приложения с использованием .Net Мои приложения обычно имеют модель домена, содержащую сущности, сопоставляемые с таблицами SQL DB. Я использую шаблон репозитория, инъекцию зависимостей и уровень обслуживания.

Недавно мы начали работать над проектами MVC 3, и у нас были дебаты, где поставить эту логику. Я пришел по тонкой архитектуре Controller/FAT Model и задавался вопросом, как бы сервисный уровень поместился в

Вариант 1 - Модель взаимодействует с услугами

Контроллер тонкий, вызывает методы на моделях. Модели "знают", как загружать себя из БД и разговаривать с репозиториями или услугами. Например. customerModel имеет метод Load (id) и загружает клиента и некоторые дочерние объекты, такие как GetContracts().

Вариант 2 - Контроллер разговаривает с сервисами

Контроллер запрашивает Сервисы для извлечения объектов модели. Логика загрузки/хранения и т.д. Находится в сервисном слое. Модель представляет собой модель чистого объекта с данными только.

Почему выбор 1 был бы лучшим выбором, особенно когда мы говорим о корпоративных приложениях, мой опыт подсказывает мне разделить проблемы, держать модели и контроллеры как можно более тонкими и иметь специализированные службы, выполняющие бизнес-логику (imcl. Взаимодействие с БД)

Спасибо за все советы и ссылки на хорошие ресурсы.

Ответ 1

Все это зависит от намерений и требований вашего приложения.

Это говорит о том, что здесь мое предложение для веб-приложений "среднего масштаба" (а не в местном ресторане, а не в Twitter/Facebook).

  • Моделирование Lean Domain

    Сухие объекты стиля POCO, предпочтительно неосведомленные к архитектуре MVC вашего веб-приложения, чтобы оставаться столь же слабо связанными с вашей конкретной реализацией, насколько это возможно. Возможно, даже библиотека классов, пригодная для использования во внешнем приложении, скажем, REST API через Веб-служба WCF).

    "Модель" в MVC наиболее точно означает модель, о которой знает контроллер, и, следовательно, модель, предназначенная для представления.

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

    В больших приложениях разработчики часто используют принципы архитектуры MVVM и начинают использовать отдельные объекты View Model. Контроллеры часто называют услуги среднего уровня, которые работают с невидимыми объектами ниже. В этом случае M в MVC наиболее точно означает View Model.

  • Надежный уровень обслуживания

    Это не означает тучную логику, но хорошо написанные одноцелевые сервисы. Хотя кодирование вашей бизнес-логики в сервисах за пределами модели является немного более "процедурным", чем чистым "ООП", оно помогает в значительной степени с помощью сочетания, тестирования и гибкого развертывания (например, развертывание n-уровня).

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

  • Lean Controllers

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

    • Службы вызовов, которые взаимодействуют с объектом/доменом Модели

    • Подготовьте модель просмотра для соответствующего вида.

    Даже аутентифицированные/санкционированные действия контроллера выполняются через внедренные службы/атрибуты.


РЕДАКТИРОВАТЬ 1:

Имейте в виду, что это не означает, что ваша модель Entity/Domain является или должна быть анемичной. ORM, репозитории и фабрики, валидация или государственная механика приветствуются. Это означает только для приложений с умеренным масштабом, модель в MVC представляет собой модель, предназначенную для контроллера, для передачи на ваш вид.

Надеюсь, этот момент успокоит апостолов Фаулера, которые считают, что модель анемических данных является анти-паттерном. В то же время он отражает немного более процедурный угол, чем ООП, где более чисто, чтобы включать поведение в моделируемые классы.

Нет никакой "истины", но при использовании этого шаблона вам будет легко создавать, тестировать и развертывать ваши приложения, сохраняя при этом много повторного использования и масштабируемости.


ИЗМЕНИТЬ 2:

Тем не менее, даже для приложений с небольшим размером, по сравнению с архитектурой (что составлено слово "ботаники"?) система слишком распространена. Например, обертывание ORM с шаблоном репозитория, а затем создание служб для использования репозитория... все это полезно для разделения беспокойства и тому подобного, но если ваш проект не требует (и вряд ли потребуется в ближайшее время ) такие вещи, не стройте его. Нет ничего плохого в пропуске репозитория вместе, написании тонких бизнес-сервисов (например, классов запросов) по сравнению с ORM или даже при наличии вашего диспетчера непосредственно с ним. Все зависит от масштаба.


ИЗМЕНИТЬ 3:

Я хотел бы отметить, что это объяснение и советы предназначены для контекстной архитектуры MVC на стороне сервера, такой как ASP.Net, а не для кластерных фреймворков, таких как Knockout или Backbone.

Ответ 2

Вам нужно знать еще кое-что о MVC, прежде чем идти дальше и обсуждать, куда положить все. Ну, если вы хотите следовать шаблону. В противном случае вы можете перестать читать сейчас.

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

MVC

Model Модель может быть любой. Это может быть веб-сервис, ваши репозитории, классы обслуживания или просто ваши модели домена. Модель - это все, что используется для получения необходимой вам информации. Рассмотрим "Модель" как слой, а не только один объект.

контроллер Контроллер - это клей. Он берет информацию из Модели и адаптирует ее к виду и наоборот.

Просмотр Представление должно отображать только то, что видит пользователь.

Помните, что вы не должны путать модель с моделью просмотра. Microsoft действительно должна была назвать папку "Модель" "ViewModels", так как это то, чем они являются. Я бы не использовал информацию из "Модели" непосредственно в представлениях. Несоблюдение этого означает, что вам нужно изменить модель, если вид изменен и наоборот.

Ответ

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

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

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

Обратите внимание, что уровень обслуживания может не понадобиться. Вы можете вызвать OR/M непосредственно с контроллеров. Но если вы обнаружите, что дублируете код или получаете толстые контроллеры, просто переместите логику на сервисный уровень. Это изменение изменится только с контроллера, поскольку вы используете правильные модели просмотра.

Ответ 3

Вариант 1: Вы могли бы подумать, что это сервис model ==. Модель также является бизнес-слоем.

Вариант 2 - анти-шаблон Anemic Domain Model. http://en.wikipedia.org/wiki/Anemic_domain_model

Ответ 4

Вариант 2 - это то, что описано как архитектура Fat Stupid Ugly Controllers (Ссылка на автора этого выражения). Это решение, как правило, против духа MVC, поскольку оно нарушает разделение проблем.