В чем разница между MVC и MVVM? - PullRequest
1224 голосов
/ 20 марта 2009

Есть ли разница между стандартным шаблоном "Model View Controller" и шаблоном Microsoft Model / View / ViewModel?

Ответы [ 23 ]

640 голосов
/ 22 августа 2010

MVC / MVVM не является выбором или / или .

Эти два шаблона по-разному возникают как в ASP.Net, так и в Silverlight / WPF.

Для ASP.Net MVVM используется для двустороннего связывания данных в представлениях. Обычно это реализация на стороне клиента (например, с использованием Knockout.js). MVC, с другой стороны, является способом разделения проблем на стороне сервера .

Для Silverlight и WPF шаблон MVVM является более всеобъемлющим и может отображаться в качестве замены MVC (или других шаблонов организации программного обеспечения по отдельным обязанностям). Одно предположение, которое часто возникало из этого паттерна, заключалось в том, что ViewModel просто заменил контроллер в MVC (как если бы вы могли просто заменить VM на C в сокращении, и все было бы прощено) .. .

ViewModel не обязательно заменяет необходимость в отдельных контроллерах.

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

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

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

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

Основные рекомендации MVCVM, которым мы следуем:

  • Просмотры отображают определенную форму данных . Они понятия не имеют, откуда поступают данные.
  • ViewModels содержат данные определенной формы и команды , они не знают, откуда поступают данные или код или как они отображаются.
  • Модели содержат фактические данные (различные контексты, хранилище или другие методы)
  • Контроллеры прослушивают и публикуют события. Контроллеры предоставляют логику, которая контролирует, какие данные видны и где. Контроллеры предоставляют код команды для ViewModel, так что ViewModel действительно многократно используется.

Мы также отметили, что в Scriptture Code-gen Framework реализован MVVM и шаблон, аналогичный Prism, а также широко используются контроллеры для разделения всей логики варианта использования.

Не думайте, что контроллеры устарели в моделях View.

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

Дополнительным преимуществом использования модели MVCVM является то, что для существования приложения в памяти должны существовать только объекты контроллера , а контроллеры содержат в основном код и небольшие данные о состоянии (т. Е. Небольшие накладные расходы памяти) , Это делает приложения, требующие меньше памяти, чем решения, для которых необходимо сохранять модели представлений, и идеально подходит для определенных типов мобильных разработок (например, Windows Mobile с использованием Silverlight / Prism / MEF). Это, конечно, зависит от типа приложения, так как вам, возможно, все равно придется сохранять время от времени кэшированные виртуальные машины для отзывчивости.

Примечание. Это сообщение было отредактировано много раз и не предназначалось специально для узкого задаваемого вопроса, поэтому я обновил первую часть, чтобы теперь охватить это тоже. Большая часть обсуждения в комментариях ниже относится только к ASP.Net, а не к более широкой картине. Этот пост должен был охватить более широкое использование MVVM в Silverlight, WPF и ASP.Net и попытаться отговорить людей от замены контроллеров на ViewModels.

249 голосов
/ 13 февраля 2013

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

Первый аббревиатура, MVC, возникла в Интернете. (Да, возможно, это было и раньше, но благодаря Интернету он популяризировался массами веб-разработчиков.) Подумайте о базе данных, HTML-страницах и промежуточном коде. Давайте немного уточним это, чтобы получить MVC: для «базы данных», давайте предположим, что база данных плюс интерфейсный код. Для »HTML-страниц« давайте предположим, что HTML-шаблоны плюс код обработки шаблонов. Для «кода между», давайте предположим, что код отображает клики пользователей на действия, которые могут повлиять на базу данных, определенно вызывая отображение другого представления. Вот и все, по крайней мере, для целей этого сравнения.

Давайте сохраним одну особенность этого веб-материала, не так, как сегодня, а так, как он существовал десять лет назад, когда JavaScript был скромным, презренным раздражением, от которого реальным программистам не постарались избежать: страница HTML по сути своей тупой и пассивный. Браузер - тонкий клиент, или, если хотите, плохой клиент. В браузере нет интеллекта. Правило перезагрузки полной страницы. »Представление« создается каждый раз заново.

Давайте вспомним, что этот веб-путь, несмотря на всю свою ярость, был ужасно отсталым по сравнению с рабочим столом. Настольные приложения - толстые клиенты или богатые клиенты, если хотите. (Даже такую ​​программу, как Microsoft Word, можно рассматривать как своего рода клиента, клиента для документов.) Это клиенты, полные интеллекта, полные знаний о своих данных. Они с состоянием. Они кэшируют данные, которые обрабатывают в памяти. Нет такого дерьма, как полная перезагрузка страницы.

И этот богатый настольный способ, вероятно, является источником второй аббревиатуры, MVVM. Не обманывайтесь буквами, пропуском C. Контроллеры все еще там. Они должны быть. Ничто не удаляется. Мы просто добавляем одну вещь: отслеживание состояния, данные, кэшированные на клиенте (и вместе с этим интеллект для обработки этих данных). Эти данные, по сути кеш клиента, теперь называются «ViewModel». Это то, что позволяет богатую интерактивность. И это все.

  • MVC = модель, контроллер, вид = по существу односторонняя связь = плохая интерактивность
  • MVVM = модель, контроллер, кэш, представление = двусторонняя связь = богатая интерактивность

Мы видим, что с Flash, Silverlight и, что наиболее важно, с JavaScript, в Интернете используется MVVM. Браузеры больше не могут по праву называться тонкими клиентами. Посмотрите на их программируемость. Посмотрите на их потребление памяти. Посмотрите на всю интерактивность Javascript на современных веб-страницах.

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

173 голосов
/ 20 марта 2009

MVVM Модель представления вида модели аналогична MVC, Контроллер вида модели

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

Рассел Восток ведет блог, обсуждая более подробно Почему MVVM отличается от MVC

88 голосов
/ 20 марта 2009

С одной стороны, MVVM - это прогрессия шаблона MVC, который использует XAML для обработки отображения. Эта статья описывает некоторые аспекты этих двух.

Основная идея архитектуры Model / View / ViewModel заключается в том, что поверх данных («Модель») есть еще один слой невизуальных компонентов («ViewModel»), которые отображают концепции данные более тесно связаны с концепциями представления данных («представление»). Это ViewModel, к которому привязывается View, а не модель напрямую.

48 голосов
/ 13 июня 2013

Вы можете увидеть объяснение шаблона MVVM в среде Windows:

В шаблоне проектирования Model-View-ViewModel приложение состоит из трех основных компонентов. enter image description here

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

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

  • ViewModel : ViewModel связывает модель данных или просто модель с пользовательским интерфейсом или представлениями приложения. Он содержит логику, с которой можно управлять данными из модели, и предоставляет данные в виде набора свойств, с которыми пользовательский интерфейс или представления XAML могут быть связаны. Например, в приложении для обмена изображениями ViewModel предоставляет список альбомов, а для каждого альбома - список изображений. Пользовательский интерфейс не зависит от того, откуда берутся картинки и как они извлекаются. Он просто знает набор картинок, представленных ViewModel, и показывает их пользователю.

41 голосов
/ 21 мая 2010

Я думал, что одно из основных отличий заключается в том, что в MVC ваш V читает ваш M напрямую и проходит через C для манипулирования данными, тогда как в MVVM ваша VM действует как прокси M, а также предоставляет функциональность вам V.

Если я не полон мусора, я удивляюсь, что никто не создал гибрид, где ваша виртуальная машина является просто прокси-сервером M, а C предоставляет все функции.

20 голосов
/ 14 декабря 2016

Простая разница: (по мотивам курса Яакова Coursera AngularJS)

enter image description here

MVC (контроллер представления модели)

  1. Модели: Модели содержат информацию о данных. Не вызывает и не использует Controller и View. Содержит бизнес-логику и способы представления данных. Некоторые из этих данных в той или иной форме могут отображаться в представлении. Он также может содержать логику для извлечения данных из некоторого источника.
  2. Контроллер: Действует как связь между видом и моделью. Просмотр вызовов Контроллер и Контроллер вызывает модель. Он в основном информирует модель и / или представление о необходимости изменения.
  3. Просмотр: Сделки с пользовательским интерфейсом. Взаимодействует с пользователем.

MVVM (модель с видом на модель)

ViewModel

  1. Это представление состояния представления.
  2. Содержит данные, отображаемые в представлении.
  3. Отвечает на просмотр событий, или логика представления.
  4. Вызывает другие функции для обработки бизнес-логики.
  5. Никогда напрямую не просит представление ничего отображать.
18 голосов
/ 25 января 2017

MVC - это контролируемая среда, а MVVM - реактивная среда.

В контролируемой среде у вас должно быть меньше кода и общего источника логики; который всегда должен жить в контроллере. Тем не мение; в веб-мире MVC легко разделяется на логику создания представления и динамическую логику представления. Творение живет на сервере, а динамическое - на клиенте. Вы часто это видите в ASP.NET MVC в сочетании с AngularJS, тогда как сервер создаст View, передаст модель и отправит ее клиенту. Затем клиент будет взаимодействовать с представлением, и в этом случае AngularJS станет локальным контроллером. После отправки Модель или новая Модель передаются обратно на контроллер сервера и обрабатываются. (Таким образом, цикл продолжается, и есть много других переводов этой обработки при работе с сокетами или AJAX и т. Д., Но по всей архитектуре идентична.)

MVVM - это реактивная среда, означающая, что вы обычно пишете код (например, триггеры), который активируется на основе какого-либо события. В XAML, где процветает MVVM, все это легко сделать с помощью встроенной инфраструктуры привязки данных, НО, как уже упоминалось, это будет работать на любой системе в любом View с любым языком программирования. Это не специфично для MS. ViewModel срабатывает (обычно это событие изменено свойством), и View реагирует на него в зависимости от того, какие триггеры вы создаете. Это может быть техническим, но суть в том, что представление не имеет состояния и не имеет логики. Это просто меняет состояние на основе значений. Кроме того, ViewModels не имеют состояния с очень малой логикой, а Модели - это Состояние с по существу нулевой логикой, поскольку они должны только поддерживать состояние. Я описываю это как состояние приложения (Модель), транслятор состояния (ViewModel), а затем визуальное состояние / взаимодействие (View).

В настольном или клиентском приложении MVC у вас должна быть Модель, а Модель должна использоваться Контроллером. В зависимости от модели контроллер изменит вид. Представления обычно привязаны к контроллерам с интерфейсами, чтобы контроллер мог работать с различными представлениями. В ASP.NET логика для MVC немного обратная на сервере, поскольку контроллер управляет моделями и передает модели в выбранное представление. Затем представление заполняется данными, основанными на модели, и имеет собственную логику (обычно это другой набор MVC, например, сделанный с AngularJS). Люди будут спорить и путать это с приложением MVC и пытаться сделать и то, и другое, и в этот момент обслуживание проекта в конечном итоге станет катастрофой. ВСЕГДА размещайте логику и управление в одном месте при использовании MVC. НЕ пишите логику представления в коде позади представления (или в представлении через JS для сети) для размещения данных контроллера или модели. Позвольте Контроллеру изменить Вид. ЕДИНСТВЕННАЯ логика, которая должна жить в представлении, - это все, что требуется для создания и запуска через интерфейс, который он использует. Примером этого является предоставление имени пользователя и пароля. Будь то рабочий стол или веб-страница (на клиенте), контроллер должен обрабатывать процесс отправки всякий раз, когда в представлении запускается действие «Отправить». Если все сделано правильно, вы всегда можете легко найти путь к веб-сайту или локальному приложению MVC.

MVVM лично мой фаворит, поскольку он полностью реактивен. Если модель меняет состояние, ViewModel слушает и переводит это состояние, и все! Затем View прослушивает ViewModel на предмет изменения состояния, а также обновляется на основе перевода из ViewModel. Некоторые люди называют это чистым MVVM, но на самом деле есть только один, и мне все равно, как вы спорите, и это всегда Pure MVVM, где View не содержит абсолютно никакой логики.

Вот небольшой пример. Допустим, вы хотите, чтобы меню нажималось при нажатии кнопки. В MVC у вас будет действие MenuPressed в вашем интерфейсе. Контроллер узнает, когда вы нажмете кнопку «Меню», а затем попросите «Вид» скользить в меню на основе другого метода интерфейса, такого как SlideMenuIn. По какой причине? Incase Controller решает, что вы не можете или хотите заняться чем-то другим, вот почему. Контроллер должен отвечать за представление, а представление ничего не делает, если только контроллер не говорит об этом. ТЕМ НЕ МЕНИЕ; в MVVM слайд-меню в анимации должно быть встроенным и общим, и вместо того, чтобы указывать на его вставку, оно будет основано на некотором значении. Так что он слушает ViewModel, и когда ViewModel говорит, IsMenuActive = true (или, тем не менее), анимация для этого имеет место. Теперь, с учетом сказанного, я хочу сделать еще одно замечание, ДЕЙСТВИТЕЛЬНО ЯСНОЕ и ПОЖАЛУЙСТА, обратите внимание. IsMenuActive, вероятно, BAD MVVM или ViewModel дизайн. При разработке ViewModel вы никогда не должны предполагать, что View вообще будет иметь какие-либо функции, а просто передавать переведенное состояние модели. Таким образом, если вы решите изменить свой вид, чтобы удалить меню и просто показать данные / опции другим способом, ViewModel не волнует. Так как бы вы управляли меню? Когда данные имеют смысл, вот как. Таким образом, один из способов сделать это - предоставить меню список опций (возможно, массив внутренних ViewModels). Если в этом списке есть данные, Меню знает, что открыть через триггер, если нет, то оно знает, как скрыть через триггер. У вас просто есть данные для меню или нет в ViewModel. НЕ решайте показывать / скрывать эти данные во ViewModel .. просто переведите состояние модели. Таким образом, представление является полностью реактивным и общим и может использоваться во многих различных ситуациях.

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

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

Если вы делаете MVC, что замечательно, то убедитесь, что ваш Контроллер управляем и полностью контролирует ваш View. Если у вас большое представление, подумайте о добавлении элементов управления в представление с разными контроллерами. Просто НЕ каскадируйте эти контроллеры на разные контроллеры. Очень сложно поддерживать. Уделите немного времени и спроектируйте вещи по-отдельности так, чтобы они работали как отдельные компоненты ... И всегда позволяйте контроллеру сообщать модели о фиксации или сохранении хранилища. Идеальная настройка зависимости для MVC в: Вид ← Контроллер → Модель или с ASP.NET (не начинайте) Модель ← Вид ↔ Контроллер → Модель (где Модель может быть одинаковой или полностью отличная Модель от Контроллера до Представления) ... конечно, единственное, что нужно знать о Контроллере в Представлении на данном этапе, это главным образом для ссылки на конечную точку, чтобы знать, где проходить Модель.

Если уТы делаешь MVVM, я благословляю твою добрую душу, но найди время, чтобы сделать это ПРАВО! Не используйте интерфейсы для одного. Пусть ваш вид решит, как он будет выглядеть на основе значений. Поиграйте с данными с видом на макет. Если в итоге у вас есть вид, который показывает вам меню (в соответствии с примером), даже если вы не хотели его в то время, то ХОРОШО. Ваше мнение работает так, как должно, и реагирует, основываясь на значениях, как и должно. Просто добавьте еще несколько требований к своему триггеру, чтобы убедиться, что этого не произойдет, когда ViewModel находится в определенном переведенном состоянии, или подайте команду ViewModel, чтобы очистить это состояние. В вашей ViewModel НЕ удаляйте это с внутренней логикой, как будто вы оттуда решаете, должен ли View его видеть. Помните, что вы не можете предполагать, есть меню или нет в ViewModel. И, наконец, модель должна просто позволить вам изменить и, скорее всего, сохранить состояние. Это где проверка и все будет происходить; Например, если Модель не может изменить состояние, она просто помечает себя как грязную или что-то в этом роде. Когда ViewModel понимает это, он будет переводить то, что грязно, и View тогда поймет это и покажет некоторую информацию через другой триггер. Все данные в представлении могут быть связаны с ViewModel, поэтому все может быть динамическим, только модель и ViewModel не имеют абсолютно никакого представления о том, как представление отреагирует на привязку. На самом деле Модель также не имеет представления о ViewModel. При настройке зависимостей они должны указывать примерно так и только так: View → ViewModel → Model (и примечание здесь ... и это, вероятно, также будет рассмотрено, но мне все равно ... НЕ ПЕРЕДАЙТЕ МОДЕЛЬ В ВИД, если только эта МОДЕЛЬ не является неизменной, в противном случае оберните ее соответствующей моделью ViewModel. В представлении не должен отображаться модельный период. это неправильно.)

Вот мой последний совет ... Посмотрите на хорошо разработанное, но очень простое приложение MVC и сделайте то же самое для приложения MVVM. У одного будет больше контроля с ограниченной или нулевой гибкостью, а у другого - без контроля и неограниченной гибкости.

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

Если я вас не смутил, попробуйте связаться со мной ... Я не против подробно рассказать об этом с иллюстрациями и примерами.

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

18 голосов
/ 28 марта 2009

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

14 голосов
/ 23 марта 2010

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

Если вы работали с MVC, вы, вероятно, когда-нибудь нашли полезным создать объекты модели, чтобы отразить состояние вашего представления, например, показать и скрыть некоторый диалог редактирования и т. Д. В этом случае вы используете модель представления.

Шаблон MVVM - это просто обобщение этой практики для всех элементов пользовательского интерфейса.

И это не шаблон Microsoft, к которому добавляется то, что привязки данных WPF / Silverlight особенно хорошо подходят для работы с этим шаблоном. Но ничто не мешает вам использовать его, например, с лицами java-сервера.

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