ASP.NET MVC - должна ли бизнес-логика существовать в контроллерах?

Дерик Уитакер опубликовал статьи пару дней назад это попало в точку, о которой мне было интересно в течение некоторого времени:должна ли бизнес-логика существовать в контроллерах?

до сих пор все ASP.NET демо-версии MVC, которые я видел, помещали доступ к репозиторию и бизнес-логику в контроллер. Некоторые даже бросают туда валидацию. Это приводит к довольно большим, раздутым контроллерам. Действительно ли это способ использовать структуру MVC? Кажется, это просто в конечном итоге будет много дублированного кода и логики, разбросанных по разным контроллерам.

6 ответов


бизнес-логика действительно должна быть в модели. Вы должны стремиться к толстым моделям, тощим контроллерам.

например, вместо:

public interface IOrderService{
    int CalculateTotal(Order order);
}

Я бы предпочел:

public class Order{
    int CalculateTotal(ITaxService service){...}        
}

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

Это заставит ваш контроллер выглядеть примерно так:

public class OrdersController{
    public OrdersController(ITaxService taxService, IOrdersRepository ordersRepository){...}

    public void Show(int id){
        ViewData["OrderTotal"] = ordersRepository.LoadOrder(id).CalculateTotal(taxService);
    }
}

или что-то вроде что.


Мне нравится диаграмма, представленная Шаблоны И Практики Microsoft. И я верю в поговорку "картина стоит тысячи слов".

Diagram shows architecture of MVC and business sevices layers


Это интересный вопрос.

Я думаю, что интересно, что большое количество примеров приложений MVC на самом деле не соответствуют парадигме MVC в смысле действительно размещения "бизнес-логики" полностью в модели. Мартин Фаулер указал, что MVC не является шаблоном в смысле Банды Четырех. Скорее, это парадигма, что программист должен добавить шаблоны to если они создают что-то за приложения игрушки.

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

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


вы можете проверить этот удивительный учебник Стивена Вальтера, который показывает проверка со слоем сервиса.

узнайте, как переместить проверку логика действий контроллера и в отдельный сервисный уровень. В этот учебник, Stephen Walther объясняет, как вы можете поддерживать sharp разделение интересов путем изоляции ваш слой с вашего уровень контроллера.


бизнес-логика не должна содержаться в контроллерах. Контроллеры должны быть максимально тощими, в идеале следовать скороговорке:

  1. найти объект домена
  2. Act on Domain entity
  3. подготовка данных для просмотра / возврата результатов

дополнительно контроллеры могут содержать некоторую логику приложения.

Итак, где я могу поместить свою бизнес-логику? в моделях.

Что такое модель? Вот это хороший вопрос. Пожалуйста, смотрите Microsoft Patterns and Practices article (слава Алехандрору за отличную находку). Здесь есть три категории моделей:

  • Посмотреть Модель: это просто пакет данных, с минимальной, если таковой имеется, логикой передачи данных из и в представления, содержит базовую проверку поля.
  • Модель Предметной Области: модель Fat с бизнес-логикой работает на одном или нескольких объектах данных (т. е. объект A в заданном состоянии, чем действие на сущность B)
  • Модель Данных: модель с памятью, логика, содержащаяся в одном объекте, относится только к этому объекту (т. е. если поле a, то поле b)

конечно, MVC-это парадигма, которая приходит в разных вариантах. То, что я описываю здесь, - это MVC, занимающий только верхний слой, vide эта статья в Википедии

сегодня MVC и аналогичные model-view-presenter (MVP) разделяют шаблоны проектирования проблем, которые применитесь исключительно к слою представления более большой системы. В простых сценариях MVC может представлять собой основной дизайн системы, достигающий непосредственно базы данных; однако в большинстве сценариев контроллер и модель в MVC имеют свободную зависимость от сервиса или уровня данных/уровня. Это все о клиент-серверной архитектуре


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