В чем разница между MVC и MVVM?
===============================

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

 

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

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

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

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

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

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

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

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

 .i1a { width: 336px; height: 280px; }
 @media(min-width: 768px) { .i1a { width: 728px; height: 90px; } }
 @media(min-width: 992px) { .i1a { width: 360px; height: 300px; } }
 @media(min-width: 1083px) { .i1a { width: 728px; height: 90px; } }

 (adsbygoogle = window.adsbygoogle || []).push({});

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

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

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

 Мы также отметили, что платформа [Sculpture code-gen](http://sculpture.codeplex.com) реализует MVVM и шаблон, похожий на Prism, а также широко использует контроллеры для разделения всей логики варианта использования.

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

  [Я начал вести блог на эту тему, который я буду добавлять по мере возможности](http://blog.hitechmagic.com/?page_id=513). Существуют проблемы с объединением MVCVM с общими навигационными системами, так как большинство навигационных систем просто используют виды и виртуальные машины, но об этом я расскажу в следующих статьях.

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

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

 

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

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

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

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

 .i2a { width: 336px; height: 280px; }
 @media(min-width: 768px) { .i2a { width: 728px; height: 90px; } }
 @media(min-width: 992px) { .i2a { width: 360px; height: 300px; } }
 @media(min-width: 1083px) { .i2a { width: 728px; height: 90px; } }

 (adsbygoogle = window.adsbygoogle || []).push({});

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

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

  

 [MVVM](http://en.wikipedia.org/wiki/Model_View_ViewModel)  **Model-View ViewModel** похож на MVC,  **Контроллер Model-View**

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

  **Russel East** обсуждает более подробно блог [Почему MVVM отличается от MVC](http://russelleast.wordpress.com/2008/08/09/overview-of-the-modelview-viewmodel-mvvm-pattern-and-data-binding/)

 

Во-первых, MVVM - это прогрессия шаблона MVC, который использует XAML для обработки отображения. [В этой статье описываются некоторые аспекты этих двух.](http://www.orbifold.net/default/?p=550)

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

 

Microsoft предоставила [объяснение паттерна MVVM в среде Windows здесь](http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj721615%28v=vs.105%29.aspx).

Здесь важный раздел:

> 
> В шаблоне проектирования Model-View-ViewModel приложение состоит из три основных компонента. ![enter image description here](/img/a2b6da2a94f75029cbdaee8f66f10bcb.png)
> 
> 
> * **Модель**: представляет модель данных, которую использует ваше приложение. Например, в приложении для обмена изображениями этот слой может представлять набор картинок, доступных на устройстве, и API, используемый для чтения и написать в библиотеку изображений.
> * **Просмотр**: приложение обычно состоит из нескольких страниц пользовательского интерфейса. Каждая страница, показанная пользователю, является представлением в терминологии MVVM. Вид код XAML, используемый для определения и стилизации того, что видит пользователь. Данные от модели отображается пользователю, а его работа ViewModel для подачи пользовательского интерфейса эти данные на основе текущего состояния приложение. Например, в приложении для обмена изображениями представления будут представлять собой пользовательский интерфейс которые показывают пользователю список альбомов на устройстве, фотографии в альбом, и, возможно, другой, который показывает пользователю определенный фотография.
> * **ViewModel**: ViewModel связывает модель данных или просто модель с пользовательским интерфейсом или представлениями приложения. Содержит логику с который управляет данными из модели и предоставляет данные в виде набора свойств, с которыми пользовательский интерфейс XAML или представления могут связываться. Например, в приложении для обмена изображениями ViewModel представляет список альбомов, и для каждого альбома выставь список картинок. Пользовательский интерфейс не зависит от откуда берутся фотографии и как их найти. Это просто знает о наборе картинок, представленных ViewModel, и показывает их пользователю.
> 
> 
> 



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

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

 

Простая разница: (Вдохновленный курсом Yaakov Coursera AngularJS)

 [![введите описание изображения здесь](/img/254a73d16d25a05714255e4ca2b5e37a.png)](/img/254a73d16d25a05714255e4ca2b5e37a.png)

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

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

  **MVVM** (модель просмотра вида модели)

  **ViewModel**

* Это представление состояния представления.
* Он содержит данные, отображаемые в представлении.
* Отвечает на просмотр событий, например, логики представления.
* Вызывает другие функции для обработки бизнес-логики.
* Никогда напрямую не запрашивает представление для отображения.

 

 **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 является **View ← Controller → Model** или с ASP.NET (не начинайте) **Модель ← View ↔ Controller → Model (где Model может быть той же самой или полностью отличной моделью от Controller до View)**... конечно, единственное, что нужно знать о Controller in View на данный момент, это в основном для ссылки на конечную точку, чтобы знать, куда возвращать модель.

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

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

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

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

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

 

MVVM - это уточнение (дискуссионное) шаблона [Модель презентации](http://martinfowler.com/eaaDev/PresentationModel.html). Я говорю спорно, потому что единственное различие заключается в том, как WPF предоставляет возможность выполнять привязку данных и обработку команд.

 

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

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

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

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

 

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

  Пытаясь пролить свет на вышесказанное, я составил этот сценарий с участием MVVM, MVP и MVC. История начинается с того, что пользователь нажимает кнопку "НАЙТИ" в приложении для поиска фильмов…:

  Пользователь: Нажмите...

  Вид: кто это? [ **MVVM | MVP | MVC** ]

  Пользователь: Я только что нажал на кнопку поиска...

  Вид: Хорошо, подожди секундочку... [ **MVVM | MVP | MVC** ]

  (Представление вызова ViewModel | Presenter | Controller…) [ **MVVM | MVP | MVC** ]

  View: Hey ViewModel | Presenter | Controller, пользователь только что нажал на кнопку поиска, что мне делать? [ **MVVM | MVP | MVC** ]

  ViewModel | Presenter | Controller: Привет, вид, есть ли поисковый запрос на этой странице? [ **MVVM | MVP | MVC** ]

  Вид: Да,… вот оно… "пианино" [ **MVVM | MVP | MVC** ]

  —— Это самое важное различие между **MVVM** и **MVP** | **MVC** ———

  Докладчик: Спасибо, просмотр,... пока я ищу поисковый запрос по модели, пожалуйста, покажите ему/ей индикатор выполнения [ **MVP** | **MVC** ]

  (Ведущий | Контроллер вызывает модель…) [ **MVP** | **MVC** ]

  ViewController: Спасибо, я буду искать поисковый запрос по модели, но не буду обновлять вас напрямую. Вместо этого я буду инициировать события для searchResultsListObservable, если есть какой-либо результат. Так что тебе лучше наблюдать за этим. [ **MVVM** ]

  (Наблюдая за любым триггером в searchResultsListObservable, View считает, что должен показывать пользователю индикатор выполнения, поскольку ViewModel не будет с ним разговаривать)

  ------------------------------

  ViewModel | Presenter | Controller: Эй, модель, у тебя есть совпадение по этому поисковому запросу?: "piano" [ **MVVM** | **MVP** | **MVC** ]

  Модель: Эй, ViewModel | Ведущий | Контроллер, позвольте мне проверить… [ **MVVM** | **MVP** | **MVC** ]

  (Модель делает запрос к базе данных фильмов…) [ **MVVM** | **MVP** | **MVC** ]

  ( Спустя некоторое время … )

  ———— Это точка расхождения между **MVVM**, **MVP** и **MVC** ————–

  Модель: Я нашел для вас список, ViewModel | Presenter, здесь он находится в формате JSON "[{" name ":" Piano Teacher "," year ": 2001}, {" name ":" Piano "," year ": 1993}] "[ **MVVM** | **MVP** ]

  Модель: Есть некоторый результат, Контроллер. Я создал переменную поля в моем экземпляре и заполнил ее результатом. Его имя "searchResultsList" [ **MVC** ]

  (Ведущий | Контроллер благодарит Модель и возвращается к Представлению) [ **MVP** | **MVC** ]

  Докладчик: Спасибо за ожидание Просмотр, я нашел для вас список подходящих результатов и упорядочил их в презентабельном формате: ["Piano Teacher 2001 ″," Piano 1993 "]. Также, пожалуйста, спрячьте индикатор выполнения сейчас [ **MVP** ]

  Контроллер: Спасибо за ожидание, View, я спросил модель о вашем поисковом запросе. Он говорит, что нашел список совпадающих результатов и сохранил их в переменной с именем "searchResultsList" внутри своего экземпляра. Вы можете получить это оттуда. Также, пожалуйста, скройте индикатор прогресса сейчас [ **MVC** ]

  ViewModel: Любой наблюдатель на searchResultsListObservable может быть уведомлен о наличии нового списка в презентабельном формате: ["Piano Teacher 2001 ″," Piano 1993 "]. [ **MVVM** ]

  Просмотр: Большое спасибо Ведущий [ **MVP** ]

  Представление: спасибо "Контроллер" [ **MVC** ] (Теперь представление задает себе вопрос: как мне представить результаты, полученные от модели, пользователю? Год выпуска фильма должен быть первым или последним…?)

  Представление: О, есть новый триггер в searchResultsListObservable…, хорошо, есть презентабельный список, теперь мне нужно только показать его в списке. Я должен также скрыть индикатор выполнения теперь, когда у меня есть результат. [ **MVVM** ]

  В случае, если вы заинтересованы, я написал серию статей [здесь](http://www.digigene.com/android-architecture-wolfkcats), сравнивая MVVM, MVP и MVC, реализовав поиск фильма приложения для Android.

 

 Внедрение сильно типизированных ViewModels в представление с использованием MVC
--------------------------------------------------------------------------------

* Контроллер отвечает за создание ViewModel и ввод его в представление. (для получения запросов)
* ViewModel - это контейнер для DataContext и состояние просмотра, такое как последний выбранный элемент и т.д.
* Модель содержит объекты DB и очень близко к схеме БД, она выполняет запросы и фильтрацию. (Мне нравится EF и LINQ для этого)
* Модель также должна учитывать репозитории и/или результаты результатов в сильные типы (EF имеет отличный метод... EF.Database.Select(querystring, parms) для прямого доступа к ADO для запроса запросов и возврата сильных типов. адреса EF - это медленный аргумент.  **EF НЕ МЕДЛЕННО**!
* ViewModel получает данные и выполняет бизнес-правила и проверку
* Контроллер в  **post back** будет обрабатывать метод ViewModel Post и ждать результатов.
* Контроллер будет вводить обновленную Viewmodel в представление. В представлении используется  **привязка только сильного типа**.
* Вид просто отображает данные и отправляет события обратно контроллеру. (см. примеры ниже).
* MVC перехватывает входящий запрос и перенаправляет его на правильный контроллер с  **сильным типом данных**

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

  **В разъяснении пункта 6 выше (по запросу)...**

Предположим, что ViewModel выглядит следующим образом:

```
public class myViewModel{
     public string SelectedValue {get;set;}
public void Post(){
    //due to MVC model binding the SelectedValue string above will be set by MVC model binding on post back.
    //this allows you to do something with it.
    DoSomeThingWith(SelectedValue);
    SelectedValue = "Thanks for update!";
 }
}

```

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

```
[HTTPPOST]   
public ActionResult MyPostBackMethod (myViewModel mvm){
         if (ModelState.IsValid)
        {
               // Immediately call the only method needed in VM...
               mvm.Post()
        }
      return View(mvm);
}

```

Обратите внимание, что для того, чтобы это действие, описанное выше, работало так, как вы намереваетесь, у вас должен быть установлен нулевой CTOR, который инициализирует вещи, которые не возвращаются в сообщение. Сообщение назад должно также отправлять обратно пары имя/значение для тех вещей, которые изменились. Если пары пар имя/значение отсутствуют, механизм привязки MVC делает правильную вещь, которая просто ничего! Если это произойдет, вы можете сказать: "Я теряю данные на почтовых серверах"...

Преимущество этого шаблона заключается в том, что ViewModel делает все "беспорядок" взаимодействием с логикой Model/Buisness, контроллер - просто роутер. Это SOC в действии.

 

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

Возможно, я ошибаюсь, но я не уверен, что MVVM действительно заставляет контроллер перемещаться. Я считаю, что концепция более соответствует: <http://martinfowler.com/eaaDev/PresentationModel.html>. Я думаю, что люди предпочитают сочетать его с MVC, а не с тем, что он встроен в шаблон.

 

Из того, что я могу сказать, MVVM сопоставляется MV MVC, что означает, что в традиционном шаблоне MVC V напрямую не связывается с M. Во второй версии MVC существует прямая связь между M и V. MVVM, по-видимому, выполняет все задачи, связанные с M и V-связью, и связывает его с тем, чтобы отделить его от C. В сущности, все еще существует более крупный рабочий процесс приложения (или реализация сценариев использования), которые не полностью учитываются в MVVM. Это роль контроллера. Удаляя эти аспекты более низкого уровня с контроллеров, они более чисты и облегчают изменение сценария использования приложения и бизнес-логики, а также делают контроллеры более многоразовыми.

 

Меня удивляет, что это очень голосовые ответы без упоминания о  **происхождении** MVVM. [MVVM](http://en.wikipedia.org/wiki/Model_View_ViewModel) - популярный термин, используемый в сообществе Microsoft, и  **создан** от Мартина Фаулера [Модель представления](http://martinfowler.com/eaaDev/PresentationModel.html). Поэтому, чтобы понять мотив шаблона и различия с другими, первая статья о шаблоне - это первое, что нужно прочитать.

 

Ну, как правило, MVC используется в веб-разработке, а MVVM наиболее популярен в разработке WPF/Silverlight.
Однако иногда веб-архитектура может иметь сочетание MVC и MVVM.

Например: вы можете использовать  **knockout.js**, и в этом случае у вас будет MVVM на вашей стороне клиента.
И ваша сторона сервера MVC также может измениться. В сложных приложениях никто не использует чистую модель. Возможно, имеет смысл использовать ViewModel в качестве "модели" MVC, и ваша реальная модель в основном будет частью этой виртуальной машины. Это дает вам дополнительный уровень абстракции.

 

MVVMC, или, возможно, MVC +, представляется жизнеспособным подходом для предприятия, а также быстрой разработки приложений. Хотя приятно отделить пользовательский интерфейс от бизнес-логики и взаимодействия, "чистый" шаблон MVVM и большинство доступных примеров лучше всего подходят для сингулярных представлений.

Не уверен в ваших проектах, но большинство моих приложений, однако, содержат страницы и несколько (многоразовых) представлений, и поэтому ViewModels действительно должны взаимодействовать в некоторой степени. Использование страницы в качестве контроллера полностью победит цели MVVM, поэтому не использовать подход "VM-C" для базовой логики может привести к... сложным конструкциям по мере созревания приложения. Даже в VB-6 большинство из нас, вероятно, прекратили кодирование бизнес-логики в событие Button и начали "ретрансляцию" команд контроллеру, не так ли? Недавно я рассмотрел много новых кадров на эту тему; моим фаворитом явно является подход Магеллана (при кодексе). Счастливое кодирование!

 <http://en.wikipedia.org/wiki/Model_View_ViewModel#References>

 

 Контроллер не заменяется ViewModel в MVVM, потому что ViewModel имеет совершенно другую функциональность, а затем контроллер. Вам все еще нужен контроллер, потому что без контроллера ваша модель, ViewModel и View не будут делать много... В MVVM у вас тоже есть контроллер, имя MVVM просто пропущено.

  MVVMC - это правильное имя по моему скромному мнению.

  Как видите, ViewModel - это просто дополнение к шаблону MVC. Он перемещает логику преобразования (например, преобразует объект в строку) с контроллера на ViewModel.

 

С практической точки зрения MVC (Model-View-Controller) является шаблоном. Однако MVC при использовании в качестве ASP.net MVC в сочетании с Entity Framework (EF) и "электроинструментами" представляет собой очень мощный, частично автоматизированный подход для приведения баз данных, таблиц и столбцов на веб-страницу для полного CRUD или R (Получить или прочитать). По крайней мере, когда я использовал MVVM, модели просмотра взаимодействовали с моделями, которые зависели от бизнес-объектов, которые в свою очередь были "обработаны вручную", и после многих усилий удавалось получить модели так же хорошо, как EF, -of коробки". С точки зрения практического программирования MVC кажется хорошим выбором, потому что он дает одну массу полезной утилиты, но по-прежнему существует возможность добавления колоколов и свистов.

 

В дополнение ко многим приведенным ответам я хотел добавить дополнительную перспективу из современной веб-страницы клиентской стороны или  **Rich Web Application**.

Аналогично, современная клиентская среда, такая как [Angular](https://angularjs.org/), следует шаблону MVC по соглашению, но также добавляет Сервис. Интересно, что он рекламируется как Model-View-Whatever (MVW). (См. [этот пост в переполнении стека](/questions/11109/what-does-mvw-stand-for).)

Кроме того, с ростом прогрессивных веб-фреймворков, таких как Angular 2, мы видим изменение в терминологии и, возможно, новый архитектурный шаблон, в котором Компоненты представляют собой View или Template и взаимодействуют с Сервисом - все это могут содержаться в модуле; и ряд модулей составляет приложение.

 

Раньше я думал, что MVC и MVVM одинаковы. Теперь из-за существования Flux я могу сказать разницу:

В MVC для каждого представления в вашем приложении у вас есть модель и контроллер, поэтому я бы назвал его view, view model, view controller. В шаблоне не указано, как один вид может связываться с другим. Поэтому в разных рамках для этого существуют разные реализации. Например, существуют реализации, в которых контроллеры общаются друг с другом, тогда как в других реализациях есть другой компонент, который посредничает между ними. Существуют даже реализации, в которых модели представления взаимодействуют друг с другом, что является нарушением шаблона MVC, поскольку к модели представления следует обращаться только с помощью контроллера вида.

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

Чтобы продемонстрировать разницу, давайте возьмем шаблон потока. Образец потока показывает, как должны взаимодействовать разные представления в приложении. Каждый вид прослушивает хранилище и запускает действия с помощью диспетчера. Диспетчер, в свою очередь, рассказывает обо всех магазинах о действии, которое только что было сделано, и магазины обновляют себя. Магазин в Flux соответствует (общей) модели в MVVM. он не является обычным для какого-либо конкретного вида. Поэтому, когда люди используют React и Flux, каждый компонент React фактически реализует шаблон MVVM. Когда действие происходит, модель представления вызывает диспетчера и, наконец, обновляется в соответствии с изменениями в магазине, который является моделью. Вы не можете сказать, что каждый компонент реализует MVC, потому что в MVC только контроллер может обновить модель представления. Таким образом, MVVM может работать вместе с Flux (MVVM обрабатывает связь между представлением и моделью представления, а Flux обрабатывает связь между различными видами), тогда как MVC не может работать с Flux, не нарушая ключевого принципа.

 

 mvc - серверная, а mvvm - клиентская (браузерная) в веб-разработке.

 

В настоящее время MVC осуждается, а не в пользу альтруистических разработчиков. 

Viper, React, MVVM, это хорошо, MVC плохо и дерьмо...

Правда или миф?

Что ж, MVC действительно стар и уверен, что у него есть свои недостатки, наиболее распространенные из которых - "массовые контроллеры представления".

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

MVC великолепен, программисты слишком небрежны.



 Короче говоря, в MVC Controler осведомлен о представлении (элементах управления), а в MVVM ViewModel не знает, кто его использует. ViewModel предоставляет свои наблюдаемые свойства и действия тому, кто может быть заинтересован в его использовании. Этот факт облегчает тестирование, поскольку в ViewModel нет ссылки на пользовательский интерфейс.