Должен ли вид не выполнять проверку?

10

Я читал « В MVC должна ли модель обрабатывать проверку? », Потому что мне было любопытно, куда должна идти логика проверки на веб-сайте MVC. Одна строка в верхнем ответе выглядит так: «контроллеры должны обрабатывать проверку, модели должны обрабатывать проверку».

Мне это понравилось, но мне стало интересно, почему мы не проводим проверку данных в View по нескольким причинам:

  1. Представления обычно имеют надежную поддержку проверки (библиотеки JS, теги HTML5)
  2. Представления могут проверяться локально, уменьшая сетевой ввод-вывод
  3. Пользовательский интерфейс уже разработан с учетом типа данных (календари для дат, счетчики для чисел), что делает его одним маленьким шагом от проверки

Проверка в более чем одном месте противоречит концепции MVC по разделению обязанностей, поэтому «делать это в обоих» кажется неуместным. Является ли проверка данных только в контроллере действительно доминирующим подходом?

WannabeCoder
источник
Проблема здесь может заключаться в ложной дихотомии: нет причины, по которой вы не можете выполнять проверку в нескольких местах, и если вы думаете о ситуации как о «или-или-не-оба», это может затуманивать ваш взгляд (каламбур!) На этот вопрос , Например, выполнение какой-либо формы проверки на стороне клиента на веб-сайте может быть очень полезным, поскольку пользователи получают мгновенную обратную связь, но это также не заслуживает доверия, поэтому не может быть единственной проверкой.
Майлз Рут

Ответы:

10

Я не думаю, что есть единственное место, где вы можете сказать, что все проверки должны пройти. Это потому, что у нас есть несколько разных конкурирующих стратегий программирования, работающих вместе на стандартном веб-сайте asp.net mvc.

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

Затем мы расширяем представление с помощью клиентского JavaScript. В наши дни это настолько продвинуто, что идея «одностраничного веб-сайта» с Jquery / knockout / angular является обычной практикой.

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

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

Кроме того, у нас часто есть требования проверки, которые не могут быть выполнены клиентом. например. 'мой новый идентификатор уникален?'

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

Ewan
источник
4
+1 и подчеркнуть: никогда не доверяйте данным, размещенным клиентом. Когда-либо.
Мачадо
Как я прочитал это: «проверка не является изолированной концепцией - все части вашего приложения должны быть проверены друг на друга в разных контекстах». Имеет смысл, даже если больше работать.
WannabeCoder
да, но также: «у вас может быть два (или более) приложения, все по разным шаблонам»
Ewan
" den · i · grate : критиковать несправедливо; унижать. " Я не думаю, что вы правильно используете это слово. Хороший ответ, хотя.
kdbanman
нет, вот что я имел в виду
Ewan
1

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

Может ли быть несколько обязанностей по проверке, чтобы рассмотреть здесь? Как вы сказали в своем № 3:

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

Так что возможно это:

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

Модель : проверка бизнес-данных. Это законная ценность в соответствии с бизнес-правилами? Да, это числовое значение (мы убедились, что в представлении), но имеет ли это смысл?

Просто мысль.

Красный человек
источник
1

Я собираюсь предположить, что вам нужно подтверждение для настойчивости.

Не только View, но Model также не должны обрабатывать валидацию. За время работы в ИТ я понял, что DDD - это один из способов убедиться, что вы действительно делаете все правильно, т.е. классы на самом деле отвечают за то, что они должны быть.

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

Давайте предположим , что вы уже так далеки , что вы используете Data Mapperвместо Active Recordупорствовать ваш домен слой. Но все же вы хотите, чтобы модели были проверены, поэтому вы добавляете проверку к вашей Модели.

interface Validation
{
    public function validate();
}

class ConcreteModel extends MyModel implements Validation
{
    public function validate() { // the validation logic goes here }
}

Логика проверки гарантирует, что вы можете правильно вставить модель в свою базу данных MySQL ... Прошло несколько месяцев, и вы решили, что хотите также хранить свои модели в базах данных noSQL, базах данных, для которых требуются другие правила проверки, чем в MySQL.

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

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

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

interface Validation
{
    public function validate();
}

class MySQLConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model here
    }
}

class RedisConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model with different set of rules here
    }
}

Если в любое время в будущем вы решите добавить другой метод проверки для другого уровня персистентности (поскольку вы решили, что Redis и MySQL больше не подходят), вы просто создадите другой Validatorи будете использовать свой IoCконтейнер, чтобы получить правильный экземпляр на основе на вашем config.

Энди
источник
1

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

Базовая концепция в тексте

... Так что всегда помните, что Модель - это не просто база данных. Даже данные, которые вы получаете от веб-сервисов, могут быть выражены в качестве модели! Да даже Atom кормит! Фреймворки, которые приводят к введению в модель, почти никогда не объясняют это заранее, что только усугубляет недопонимание.

а также

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

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

Принимая запись о человеке, каждый человек должен иметь уникальный идентификационный номер, указанный в стране. Эта проверка (как правило) выполняется UNIQUEпроверкой ключей базой данных. Каждый заданный идентификационный номер должен удовлетворять некоторым шагам управления (сумма нечетных цифр должна быть равна сумме четных цифр и т. Д.). Этот тип контроля должен быть сделанModel

Контроллер собирает данные Modelи передает их View, или наоборот, собирает пользовательские данные Viewи передает их Model. Любые ограничения доступа к данным и их проверки не должны выполняться Controller. Именно Controllerон собирает данные cookie и Modelпроверяет, является ли это действительным сеансом или пользователь имеет доступ к этой части приложения.

Viewэто пользовательский интерфейс, который собирает данные от пользователя или представляет данные пользователю. Простые проверки могут быть выполнены с помощью, Viewнапример, введенного пользователем адреса электронной почты или нет (таким образом, это также может быть сделано в представлении) IMO.

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

Падший ангел
источник
Просто для того, чтобы подчеркнуть, что представление, касающееся только пользовательского интерфейса, не означает, что оно не может выполнить какую-либо форму проверки - предоставление мгновенной обратной связи пользователям, когда они делают ошибку, на самом деле является действительно важной частью того, почему сценарии на стороне клиента являются полезно, в контексте MVC применяется к веб-сайтам.
Майлз Рут
@MilesRout на самом деле, я имею в виду, что, Simple checks can be done by the View like the user input e-mail address or not может быть, это не так ясно. Но то, что вы сказали, также верно для меня, простые и легкие проверки могут быть легко сделаны в представлении.
FallenAngel
Я не был с тобой не согласен.
Майлз Раут
0

Представления должны выполнять проверки для следующих целей:

  1. Проверка внешнего интерфейса может уменьшить трафик данных на вашем сервере.
  2. ) он обрабатывает недействительные данные, прежде чем он может путешествовать на вашем сервере.
  3. ) если вы хотите более высокий уровень безопасности, лучше использовать комбинацию проверки на стороне пользователя и на стороне сервера.
лазурь
источник