Я решил сделать большой шаг вперед в сторону MVC для всех создаваемых мной новых сайтов. У меня вопрос, можно ли проводить обработку на уровне модели.
Случай, поднявший этот вопрос, - видео-сайт. У меня есть класс (модель) видео, и одна из вещей, которые мне нужно делать, когда пользователь просматривает видео, мне нужно, чтобы представление было зарегистрировано в базе данных. Я не уверен, нужно ли мне добавить запрос в контроллер или можно добавить метод addView в класс Video.
Для меня основной вопрос: какими методами я ограничен в моделях? Может ли это быть что-нибудь или это должны быть только методы доступа (также известные как getValue / setValue)?





Я думаю, ваша модель как раз то, что вам нужно. Теперь ваша модель обязательно состоит только из ваших классов сущностей. На мой взгляд, ваша модель будет включать в себя ваши сущности, а также любую бизнес-логику, которую вам нужно реализовать. Ваш контроллер должен просто обрабатывать ввод-вывод для представления, вызывая методы модели для выполнения действий, вызываемых пользователем через пользовательский интерфейс (представление).
Поскольку вы можете использовать любой код модели с MVC (не только LINQ), краткий ответ - да. Что делать в модели должен - это, возможно, лучший вопрос. На мой вкус, я бы добавил свойство ViewCount (которое, вероятно, соответствует столбцу в таблице Video, если вы не отслеживаете каждого пользователя, и в этом случае оно будет в таблице UserVideo). Затем с помощью контроллера вы можете увеличить значение этого свойства.
Точно - если это было непонятно, я говорил о реализации этого свойства в модели. А затем вы можете абстрагироваться от этого, создав метод в модели под названием RecordView или что-то в этом роде, и при этом вы увеличиваете свойство ViewCout, а также делаете все, что может потребоваться.
У Ruby on Rails девиз тонкий контроллер, толстая модель. Это относится не только к Rails, и это следует практиковать с любым фреймворком mvc.
Имейте в виду, что существует множество вариаций MVC и нет настоящего «правильного способа» что-то делать. В конечном счете, то, как вы разрабатываете свои классы, зависит от личных предпочтений. Однако, поскольку вы просили совета по дизайну, вот мои два цента:
Бизнес-логика принадлежит контроллеру. Держите его подальше от модели и просматривайте.
Из множества вариаций шаблона MVC, стиль пассивный взгляд кажется самым простым для тестирования. В пассивном представлении ваши классы построены следующим образом:
Ваш контроллер «умный»: он вносит изменения в базу данных, обновляет модель и синхронизирует представление с моделью. Помимо ссылки на модель и представление, контроллер должен хранить как можно меньше информации о состоянии.
Модель «тупая», то есть она содержит только состояние представления и никакой дополнительной бизнес-логики. Модели не должны содержать ссылку ни на представление, ни на контроллер.
Представление «глупо», то есть оно только копирует информацию из модели в пользовательский интерфейс и вызывает обработчики событий, которые обрабатываются контроллером. Представление не должно содержать дополнительной бизнес-логики. Представления не должны содержать ссылку на контроллер или модель.
Если вы пурист MVC, то для модели не имеет смысла обновлять себя или базу данных, поскольку эти обязанности принадлежат контроллеру, поэтому было бы целесообразно создать метод addView для вашего класса Video с помощью нет.
Но в этой модели вы, как правило, генерируете слои внутри слоя контроллера ... Это немного сложнее.
Я не согласен с этим подходом по тем же причинам, которые упоминал tvanfosson - вы часто делаете одни и те же действия с нескольких контроллеров, поэтому размещение бизнес-логики в контроллере создает беспорядок.
Контроллер может вызывать действия для изменения модели, но логика внесения изменений инкапсулирована внутри модели. Это локализует его для всех контроллеров. Он может быть на уровне сервиса или в классах сущностей, но должен быть частью модели. Модель - это данные + логика.
По крайней мере, в этих случаях BL необходимо полностью абстрагировать от базы данных; и проработайте Модель, чтобы выполнить логические действия.
-1 Я считаю, что это просто-напросто неправильно. Бизнес-логика принадлежит модели, а не представлению ИЛИ контроллеру. Контроллеры должны быть очень простыми, по возможности RESTful. Для средств поиска, фильтров, записей по пользователю, что угодно, для всех этих моделей ответом являются именованные области и другие конструкции.
Полностью согласен с Майклом Даррантом. Тонкие глупые контроллеры с толстыми, умными моделями (и добавление 4-го уровня для настойчивости) - это путь IMO.
Вот как бы я это сделал. Он должен быть действителен практически на любом языке.
Представление инициирует вызов метода для метода OnView () контроллера, а затем отобразит все, что контроллер вернет ему (контролируемым образом, конечно ... Я думаю, что ваше представление будет содержать компонент видеоплеера, так что вы собираетесь получить какое-то видео с контроллера)
В вашем контроллере есть метод OnView (), который выполняет 3 вещи: создает экземпляр объекта Video (т. Е. Использует ваш уровень данных для получения объекта модели), вызывает метод updateViewCount () для объекта Video и отображает видео (возвращая предположительно объект Video для View).
Объект модели Video содержит данные, представляющие ваше видео и все необходимое, что вам нужно, включая updateViewCount (). Обоснованием этого является то, что количество просмотров видео имеет (агрегирование). Если «счетчик просмотров» должен быть сложным объектом, а не просто целым числом, пусть будет так. Ваш уровень данных, который создает видеообъекты из их примитивного представления на диске (база данных?), Также будет отвечать за загрузку и создание соответствующего объекта подсчета просмотров как часть создания видео.
Итак, это мои 0,02 доллара. Вы можете видеть, что я создал четвертую вещь (первые три - это модель, представление и контроллер), то есть уровень данных. Мне не нравится загрузка и сохранение объектов модели, потому что тогда они должны знать о вашей базе данных. Мне не нравятся контроллеры, выполняющие загрузку и сохранение напрямую, потому что это приведет к дублированию кода в контроллерах. Таким образом, отдельный уровень данных, к которому должны иметь прямой доступ только контроллеры.
В заключение, вот как я смотрю на представления: все, что делает пользователь, и все, что пользователь видит, должно проходить через представление. Если на экране есть кнопка с надписью «play», она не должна напрямую вызывать метод контроллера (во многих языках это не представляет опасности, но некоторые, например PHP, потенциально могут это допускать). Теперь метод "play" представления просто развернется и вызовет соответствующий метод на контроллере (которым в примере является OnView) и больше ничего не сделает, но этот уровень концептуально важен, хотя он функционально не имеет значения. Аналогичным образом, в большинстве ситуаций я бы ожидал, что ваше представление будет воспроизводить видеопоток, поэтому данные, возвращаемые контроллером в представление, будут потоком в формате, который требуется представлению, что не обязательно может быть вашим точным объектом модели (и добавлением этот дополнительный уровень развязки может быть рекомендован, даже если вы можете использовать объект Video напрямую). Это означает, что я могу заставить свой метод OnView принимать параметр, указывающий, какой формат видео я хочу вернуть, или, возможно, создать отдельные методы просмотра на контроллере для каждого формата и т. д.
Достаточно долго запыхался для тебя? : D Я ожидаю нескольких огорчений от разработчиков Ruby, которые, кажется, имеют несколько иное (хотя и не несовместимое) представление о MVC.
С MVC люди, похоже, не могут уместить четыре уровня в три.
Парадигма MVC правильно обращается к хранилищу данных в нет. И это «четвертый слой». Модель имеет обработку; но так как он также обращается к данным, программисты также помещают туда SQL. Неправильный. Создайте уровень абстракции данных, который является единственным местом, которое должно взаимодействовать с внутренним хранилищем. MVC должен быть DMVC.
О, это просто: модели. Только модели. :-)
Лучше бы в модели реализовать то, что происходит при просмотре видео. Что произойдет, если вы захотите просматривать видео с нескольких контроллеров? Что происходит, когда вы хотите изменить ведение журнала «просмотр видео» (например, записать также идентификатор текущего пользователя).