[Не доделано - переработать]
Отделить UI-код (View) от кода логики (Presenter, Controller, ViewModel и т. д.) и кода обработки данных (Model).
State: Состояние данных является одной из самых больших проблем в пользовательском интерфейсе. State означает текущее изображение данных вашего пользовательского интерфейса. В веб-терминологии это может быть переменная сеанса, а в приложении Windows это могут быть простые данные уровня пользовательского интерфейса. Чем больше пользовательский интерфейс поддерживает состояний, тем больше увеличивается его сложность.
Logic: Пользовательский интерфейс обычно содержит логику пользовательского интерфейса, например, манипулирование текстовыми полями, комбинированными полями или любыми другими элементами пользовательского интерфейса. Чем больше такой логики существует в пользовательском интерфейсе, тем более сложным он становится.
Модель - это набор классов предметной области.
Модель ничего не должна знать про:
1. Способ хранения данных (где хранится, в каком формате и т.д.)
2. Способ отображения (GUI)
3. Какое-либо внутреннее (жесткий диск, ОЗУ, процессор...) или периферийное оборудование (клавиатура, мышь, принтер, платежный терминал...)
4. Протоколы связи (http, ftp, netbios ...)
5. ОС и взаимодействия со внешним ПО (например экспорт в Excel через OLE)
--------------
Какие реальные проблемы решают паттерны и каким образом?
При разработке UI решаются три задачи:
(M) получение/сохранение/работа с данными,
(V) рендеринг интерфейса,
(x) увязывание данных с интерфейсом.
Смешивание всех этих задач в одном месте даёт многократное увеличение сложности результата, что в свою очередь для навороченного интерфейса приводит к быстрой и неизбежной потере контроля над кодом. MV* решают эту проблему путём разделения сфер влияния и уменьшения связей между частями кода - вместо умножения сложностей всех трёх частей получить в идеале их сумму. Идеал достигается при условии, что все три части вообще ничего не знают друг о друге.
Model
Это данные, которые отображаются с помощью визуального интерфейса. Модель НЕ отвечает за получение и сохранение данных, это делает кто-то внешний по отношению к Модели.
View
Это собственно визуальный интерфейс. В MFC и WinForms это код создания формы, в ASP.NET — html, в WPF и Silverlight – XAML.
MVC
MVC – это базовый паттерн, классика жанра. Я бы даже сказал, что сегодня это скорее общий термин для группы паттернов, которым ввиду разнообразия не имеет смысла давать отдельные названия.
В идеале все три части должны знать друг о друге как можно меньше. Паттерны отличаются тем, кто о ком что знает и насколько подробно.
В MFC и WinForms контроллер увязывает модель с интерфейсом, заполняет форму взятыми откуда-то из Service данными и реагирует на события от интерфейса. Контроллер знает всё о модели и интерфейсе, интерфейс знает о контроллере, модель не знает ничего. К тому же в WinForms используя binding можно значительно ослабить связь между всеми тремя частями. В некоторых реализациях, например, ASP.NET MVC разработчикам удалось добиться того, что интерфейс (View) напрямую не взаимодействует с контроллером, а контроллер знает совсем чуть-чуть о View. Зато View всё знает о модели. Более того, модель специально строится под нужды интерфейса и, если в приложении есть другие модели, например, модель данных приложения или объектная модель приложения, то это проблемы самого приложения, а ASP.NET MVC хочет свою собственную модель для своих собственных нужд.
MVP
Задача MVP – полностью отделить View от контроллера и дать возможность использовать сменные View. Сама по себе идея сменных View утопична. В теории это выглядит красиво. Но мы все прекрасно знаем, чем теория отличается от практики. На практике же получается, что для более менее сложных UI контроллеры, например, для Web и Win, отличаются принципиально, начиная с обработки событий и заканчивая специфичной потребностью в данных. А для простых UI, где это могло бы сработать, встаёт вопрос о целесообразности применения данного паттерна вообще, т.к. за счёт его применения усложнение мы получим по любому, а вот будет ли от этого хоть какой-нибудь эффект ещё вопрос.
Но! MVP как раз помогает нам решать проблему тестирования наших визуальных компонент и уже поэтому имеет право на существование. По сути MVP отличается от MVC лишь введением интерфейса между View и контроллером, который теперь назван презентером. Т.е. на диаграмме к трём квадратикам добавляется четвёртый – интерфейс и все связи от модели и контроллера к View протягиваются через него.
MVVM
Говоря о WinForms я уже упоминал binding. Binding позволяет контроллеру знать поменьше как о модели, так и о View. Связь модели и View задаётся декларативно во View, в результате хоть и получается связь View -> Model, но не очень сильная. Хотя, с другой стороны и не очень надёжная. В отличие от WinForms в XAML binding ещё более продвинут, и позволяет связывать с формой не только данные, но и действия. Из функционального программирования мы знает, что функция – это объект, а раз так, то никто не мешает этот объект задать в виде свойства нашей модели и декларативно связать его с соответствующим свойством во View. В результате мы получаем идеал ООП – самодостаточный объект с инкапсулированными данными и поведением, который абсолютно ничего не знает о View.
ViewModel и есть этот самый объект. Фактически мы совместили в одном объекте функции модели и контроллера и назвали вот так замысловато. Это и понятно. От контроллера не осталось практически ничего. Функции обмена данными View и модели полностью берёт на себя binding. Реакцию модели на действия пользователя обеспечивается этим объектом, опять же посредством binding. И главное, такие объекты легко тестировать по причине их самодостаточности.
Остаётся лишь один неясный вопрос, а что же такое первое M в MVVM. Видимо это модель данных или какая-то другая модель приложения. Последнее время тенденция создания отдельной модели для конкретного View становится всё более популярной и с практической точки зрения это вполне оправдано. ASP.NET MVC вообще объявил модель своей собственностью, а на остальные ему начхать.
Итого
Всё в этом мире существует по какой-либо причине. Поняв эту причину можно понять это самое “всё”. В программировании большинство вещей, особенно сходу не совсем понятных, крутится вокруг управления сложностью. Сложность в разработке UI в наличии сильных связей между M, V и C. Абсолютно все MVC паттерны решают одну и ту же задачу – устранение или ослабление этих связей. Это — ключевой момент в понимании этого паттерна. Разбираясь, как работает тот или иной MVC паттерн, ищите эти связи и разбирайте способы их устранения. Поняв это, вам не составит труда понять сам паттерн и его предназначение. И главное понять, а надо ли оно вам.