IMO ...
MVC - это очень общий шаблон проектирования, который не обязательно говорит, что хорошо, а что плохо. Там есть модель, вид и контроллер. Обязанности каждой из этих вещей зависят от вида MVC, а вид MVC, который вы выбираете, должен зависеть от сложности вашего проекта. Например, если у вас есть проект, управляемый доменом, примеры, приведенные здесь другими, не будут работать очень хорошо.
Итак, в самом его основании:
Модель: объект, данные которого будут отображаться в представлении. Будь то DTO или модель предметной области, здесь на самом деле не определено, но я поделюсь своими мыслями об этом через секунду.
Вид: это то, что видит пользователь и как он взаимодействует. Любой код или логика здесь должны напрямую поддерживать представление. Другими словами, бизнес-логика ZERO, логика доступа к данным ZERO, знание ZERO того, что физически видит пользователь. Либо веб-форма, форма окна рабочего стола, либо активность (мобильная) и т. Д. *
Контроллер: Вероятно, самая неоднозначная часть этой головоломки. Одно можно сказать наверняка: он является посредником между представлением и «моделью», а также решает, что будет дальше, или, скорее, он «контролирует» поток. Но важно не зацикливаться на этом описании. Что эта вещь действительно делает, зависит от вашего понимания MVC. Поэтому я поделюсь тем, как я смотрю на это в веб-контексте; но в принципе, просто проведите грань между управлением потоком службы и фактическим выполнением службы.
MVC, для меня, это не другой способ описания N-уровня, как могут утверждать некоторые люди. В MVC нет слоев, так как MVC фактически находится на вашем уровне представления . Каждый элемент MVC фактически живет на уровне представления, и шаблон MVC просто говорит, что вы должны разделить проблемы между получением данных и их отображением:
- Модель: как выглядят данные. На самом деле просто структура, которую представление будет использовать для получения своих данных
- Просмотр: собственно отображение
- Контроллер: выяснение, где взять данные для модели или даже самой модели.
Если вы можете принять это утверждение, тогда оно должно помочь прояснить, что на самом деле представляет собой модель в этом контексте. Модель НЕ является объектом доступа к данным, а модель НЕ является моделью предметной области, потому что ни одна из этих вещей не должна быть на вашем уровне представления. Так что у нас остается либо ViewModel (MVVM), либо DTO. Я собираюсь пойти с DTO ради простоты.
Итак, если мы приняли DTO как тип модели, о которой мы говорим, когда говорим «модель» в MVC, то где мы ее получим? Если контроллер не должен портить доступ к данным, то где? Как насчет вашего уровня обслуживания? Ваш уровень обслуживания содержит все «как» вашего приложения. Это слой "Делай вещи". Поэтому, если ваше представление хочет создать пользователя, оно соберет данные и передаст их контроллеру. Контроллер решает, какую службу (ы) вызвать для выполнения задачи, и отправляет ей запрос с необходимыми данными. Сервисный уровень отвечает DTO. Этот DTO можно использовать напрямую или добавить в другую модель (например, если было вызвано несколько служб).
Важными моментами являются:
- Контроллер ничего не знает о вашем домене (если он у вас есть), он знает только о ваших доступных сервисах и способах их вызова.
- Абсолютно нет логики business , выполняемой контроллером. Например, если вам нужно было отправить приветственное письмо как часть операции CreateUser, это не будет инициировано контроллером, поскольку это технически бизнес-правило. Он будет обрабатываться между вашим сервисом и доменом.
- По моему мнению, ваш контроллер не должен осуществлять доступ к данным. Это должно быть делегировано на сервисный уровень. Многие учебные пособия показывают, как контроллер взаимодействует с репозиториями, что, я думаю, хорошо, потому что это абстракция, но прямой доступ к данным должен быть абсолютным, нет нигде на уровне представления.
Опять же, это в веб-контексте. Если вы работаете с MVC в приложении для Android, возможно, у вас не будет сервисного слоя или домена. Возможно, вы будете взаимодействовать с различными типами объектов. Лично я всегда использую сервисные или прикладные уровни и по нескольким причинам, которые могут или не могут рассматриваться как ценные для других.
Так что в MVC.Net контроллер больше похож на API; представление и API являются двумя различными средами представления, которые предназначены для совместной работы (внутренний контроллер представляет данные, внешний контроллер строит модели с этими данными и связывается с представлением). В Angular контроллер больше похож на то, о чем мы здесь говорим. Слои, слои слоев, кажется. Это немного сбивает с толку концептуализации, но на самом деле концепция никогда не выходит за пределы уровня представления.
Но подведем итог: контроллер «контролирует» операции и данные, поступающие в вашу систему и из нее, в и из представления, но на самом деле не делает бизнес . Детали этого процесса сильно зависят от философии вашего проекта.

Итак, здесь, на этой диаграмме, я сгруппировал концепции, чтобы показать MVC внутри N-уровня в типичном монолитном приложении. Связь проходит слева направо и не перепрыгивает через какой-либо другой слой (см .: Луковая архитектура) На уровне представления контроллер знает о модели и представлении, но представление и модель по большей части ничего не знают. Однако во многих разновидностях MVC, включая ASP.Net и MVVM, представление может знать об интерфейсе модели или прототипе (но не об экземпляре модели), чтобы связываться с ним.
Контроллер будет обрабатывать манипуляции с моделью (или просматривать модель в этом контексте), что означает, что ему может потребоваться информация об объекте домена и доменных службах. При желании вы можете вставить прикладной уровень между уровнем представления и доменом, если вам нужно более многократно используемое приложение (например, ваше приложение может иметь несколько головок: веб-API и приложение для настольных компьютеров, мобильное приложение и т. Д.), Чтобы обеспечить транзакционная граница и дальнейшая изоляция. Важно, чтобы представление не имело знания / зависимости от доменных объектов в этой архитектуре - поэтому существует отдельная модель для представления. Задача модели в MVC - создать модель для вида . То есть это модель, специально разработанная для обслуживания представления, а не домена. Это нормально для модели представления, чтобы обернуть / адаптировать модель предметной области до тех пор, пока она никогда не будет опубликована и / или случайно сериализована.
Кстати, «уровень представления» в веб-API, на мой взгляд, представляет собой сериализованный контракт (например, JSON или XML). Так относитесь к этому соответственно.