Что такое использование модели в MVC? Это действительно полезно?

Я новичок в этом, так что терпите меня. В последнее время я использовал один MVC-фреймворк в нескольких проектах, и через некоторое время я разочаровался в ощущаемой полезности "Модели" в MVC.

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

Если вся логика должна быть помещена в контроллер в первую очередь, я не вижу никакого смысла для модели, особенно Active-Record. У нас уже есть такой надежный и простой в использовании язык для общения с базой данных, я прав? Это называется SQL. Для меня, когда модели реализованы как active-record, их полезность зависит от того, хотите ли вы, чтобы ваше приложение помещалось в нескольких базах данных.

Итак, что я спрашиваю, если вы используете только одну базу данных, зачем беспокоиться о моделях и Active-Records? Почему бы просто не использовать SQL? Почему дополнительный уровень сложности? У вас, ребята, есть какие-нибудь примеры из практики / истории из реальной жизни, в которых модели на самом деле могут работать лучше, чем просто использование класса базы данных и отсутствие SQL?

Опять же, мне жаль, если я выгляжу таким невежественным, но я действительно не знаю, почему модели важны. Спасибо за ответы.

5 ответов

Решение

Во-первых, вы предполагаете, что уровень модели обязательно использует какой-то ORM, чтобы абстрагировать SQL. Это не так: вы можете создать слой модели, который слабо связан со слоем контроллера, но тесно связан с конкретной СУБД, и поэтому избегайте использования полнофункционального ORM.

Существует несколько библиотек ORM, таких как Hibernate (Java), NHibernate (.NET), Doctrine (PHP) или ActiveRecord-Rails (Ruby), которые действительно могут генерировать все реальные операторы SQL для вас; но если вы считаете, что ORM не нужен, и вы хотите определить все операторы SQL вручную, не используйте их.

Тем не менее, ИМХО, это НЕ означает, что вы должны просто разместить всю свою логику, связанную с БД, внутри уровня контроллера. Это называется подходом "жирного контроллера", и это путь, который много раз ведет к раздутому, не поддерживаемому коду. Вы можете использовать его для простых CRUD-проектов, но все, что за этим потребует, потребует наличия настоящей "Модели".

Вы, кажется, заботитесь о MVC. Пожалуйста, прочитайте также кое-что о TDD. Один мудрец однажды сказал: " Устаревший код - это код без тестов". Когда вы узнаете, что автоматизированные модульные тесты так же важны, как и "настоящий" код, вы поймете, почему в корпоративном приложении так много уровней и почему ваш уровень модели должен быть отделен от контроллера. Блок кода, который пытается сделать все (представление, бизнес-логика, сохранение данных) просто не может быть легко протестирован (и, между прочим, не отлажен).

редактировать

"Модель" - это немного нечеткий термин. В зависимости от того, где вы смотрите, это может означать что-то немного другое. Например, программисты PHP e Ruby часто используют его как синоним активной записи, что не совсем точно. Некоторые другие разработчики, похоже, считают, что "модель" - это просто своего рода DTO, что тоже не правильно.

Я скорее использую определение модели, как видно из Википедии:

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

Таким образом, модель является самым большим и самым важным уровнем в большинстве приложений MVC. Вот почему он обычно делится на подуровни: Домен, Сервис, Доступ к данным и так далее. Модель обычно предоставляется через домен, потому что именно там вы найдете методы, которые вызовет ваш контроллер. Но уровень доступа к данным также относится к "модели". Все, что связано с постоянством данных и бизнес-логикой, принадлежит ему.

В большинстве реальных ситуаций данные, поступающие от пользователя, не попадают прямо в базу данных.

Он часто должен быть проверен, отфильтрован или преобразован.

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

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

Большинство современных сред MVC предоставляют способы указания контрактов в соответствии с требованиями достоверности данных, такие как Rails.

Вот пример из http://biodegradablegeek.com/2008/02/introduction-to-validations-validation-error-handling-in-rails/:

class Cat
  validates_inclusion_of :sex, :in => %w(M F), :message => 'must be M or F'
  validates_inclusion_of :vaccinated, :in => [true,false]
  validates_inclusion_of :fiv, :in => [true,false]
  validates_inclusion_of :age, :within => 1..30
  validates_each :weight do |record, attr, value|
      record.errors.add attr, 'should be a minimum of 1 pound' if value and value  /^[01][0-9]\/[0-9]{2}\/[0-9]{4}$/
  validates_length_of :comment, :allow_blank => true, :allow_nil => true, :maximum => 500
end

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

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

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

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

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

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

Чтобы привести более конкретный пример (если не полностью реалистичный): теоретически вы могли бы написать все свое приложение так, как вы извлекали все данные с помощью SQL-запросов. Но позже вы поняли, что хотите использовать какой-нибудь движок noSQL (CouchDB и т. Д.), Потому что вам нужно горизонтальное масштабирование.

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

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

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

Это не идеальное объяснение (далеко не так), но я надеюсь, что это поможет.

Модели должны содержать всю вашу логику. Контроллер отвечает только за логику, связанную с взаимодействием с пользователем. Все связанные с доменом функции (так называемая "бизнес-логика") должны быть размещены в модели и отделены от кода контроллера. Таким образом, вы можете добиться лучшего разделения проблем и повторного использования кода.

Например, предположим, вы пишете приложение, позволяющее пользователям вводить информацию о себе и получать рекомендации по питанию.

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

С другой стороны, вы помещаете код для входа в систему пользователей, показывает форму, собираете данные формы, проверяете ее в контроллере. Таким образом, например, вы можете позже добавить API в ваше приложение (которое использует другой код для аутентификации, получения данных от пользователя, проверки и т. Д.) И повторно использовать код для генерации результатов (из модели).

Это всего лишь пример того, для чего модель хороша.

Я всегда связываю Модель с данными независимо от того, где они присутствуют или как они представлены. В MVC V отображаются данные, а C дескрипторы меняются. Даже если у вас есть все данные, которые будут представлены на экране в HashMap внутри вашего контроллера; что HashMap будет называться моделью.

Другие вопросы по тегам