Где "уровень бизнес-логики" вписывается в приложение MVC?


во-первых, прежде чем кто-то кричит обман, мне было трудно суммировать его в простом названии. Другой заголовок мог бы быть "в чем разница между моделью домена и моделью MVC?"или "что такое модель?"

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

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

возьмем простой пример. AccountController, включенный в проект MVC по умолчанию. Я прочитал несколько мнений о том, что включенный код учетной записи имеет плохой дизайн, нарушает SRP и т. д.. так далее.. Если бы нужно было разработать "правильную" модель членства для приложения MVC, что бы это было?

Как бы вы отделить ASP.NET услуги (поставщик членства, поставщик ролей и т. д..) от модели? Или ты вообще хочешь этого?

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

кто-нибудь пролить свет на этот вопрос?

4 83

4 ответа:

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

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

дело в том, что при работе с кредитными картами - я должен требовать cvv при обработке платежа, но я не могу хранить cvv (это штраф в размере 50 000 долларов США). Но я также хочу, чтобы вы могли редактировать свою кредитную карту - изменение адреса, имени или даты истечения срока действия. Но вы не собираетесь давать мне номер или cvv при его редактировании, и я, конечно же, не собираюсь вводить номер вашей кредитной карты обычный текст на странице. Мой домен имеет эти значения, необходимые для сохранения новой кредитной карты, потому что вы даете их мне, но моя модель редактирования даже не включает номер карты или cvv.

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

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

<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) && 
    Model.SomeObject.SomeInt == 3 && ...) { %>

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

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

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

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

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

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

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

по-моему,

модель

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

Бизнес-Логика -

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

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

Так, Контроллер попросит службу приложений для модели, и поток будет идти, как,

    Controller->Application Services(using domain services)->Model

шаблон MVC и Asp.net структура не делает различий в том, какой должна быть модель.

собственные примеры MS включают классы персистентности в модели. Ваш вопрос о членстве в модели. Это зависит от обстоятельств. Классы в вашей модели принадлежат чему-то? Есть ли связь между тем, кто входит в систему и какие данные отображаются? Есть ли фильтрация данных часть системы разрешений, которая доступна для редактирования? Кто последний раз обновлял или редактировал объектную часть вашего домена как в ком-то еще нужно это видеть или что-то для поддержки бэкэнда?

пример электронной почты также зависит. Вы знакомы с доменом eventing или eventing в частности? У вас есть отдельная служба для отправки электронной почты? Является ли акт отправки электронной почты частью вашего домена или это проблема уровня приложения за пределами вашей системы? Должен ли пользовательский интерфейс знать, если письмо было отправлено успешно или нет? Есть ли письма, которые не могут отправить нужно повторить попытку? Из содержания отправленная электронная почта должна храниться для поддержки или требований к обслуживанию клиентов?

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

ваши требования/сроки/ресурсы превратятся в архитектуре вашей системы. Даже модель получения дохода может иметь эффект. Вы также должны рассмотреть шаблон, который вы снимаете для. DDD сильно отличается от persistence-as-model приложения и все помои между ними также действительны для некоторых приложений. Вы снимаете для тестирования приложения? Все это имеет эффект.