Comments 36
Открыл для себя давно уже паттерн MVPVM для XAML платформ. Это просто смесь MVP + MVVM.
Там где удобно использовать bindings — просто используешь всю мощь MVVM. А там где нужно вызвать что-то вроде ListBox.ScrollIntoView — просто используешь мощь MVP — делаешь метод для интерфейса представления и его просто вызываешь.
Там где удобно использовать bindings — просто используешь всю мощь MVVM. А там где нужно вызвать что-то вроде ListBox.ScrollIntoView — просто используешь мощь MVP — делаешь метод для интерфейса представления и его просто вызываешь.
+1
Спасибо, добрый человек.
Во-первых, спасибо Вам за статью, написанную ранее по этой же теме (я про Ваш блог).
Во-вторых, MSDN-журнал уже писал об этом.
IMHO, MVPVM отлично подходит для Windows Forms. Для каждого интерфейса представления должна быть реализована функция, типа «InitializeBindings», где для каждого контрола связывание должно происходить.
Во-первых, спасибо Вам за статью, написанную ранее по этой же теме (я про Ваш блог).
Во-вторых, MSDN-журнал уже писал об этом.
IMHO, MVPVM отлично подходит для Windows Forms. Для каждого интерфейса представления должна быть реализована функция, типа «InitializeBindings», где для каждого контрола связывание должно происходить.
0
IMHO, MVPVM отлично подходит для Windows Forms. Для каждого интерфейса представления должна быть реализована функция, типа «InitializeBindings», где для каждого контрола связывание должно происходить.
Это уже тонкости реализации. Я просто говорю брать лучшее от двух. В случае с MVP приходится писать много кода, который связывает View и Presenter, в случае с MVVP этого делать не нужно в 80% случаях, но в оставшихся 20% (ототбражение Popup, вызова ListBox.ScrollIntoView ) придется писать безумных Iteraction, хотя иногда это намного проще решается при помощи MVP связки.
Когда у меня была идея написать больше одного приложения для Windows Store я сделал что-то вроде Framework для себя github.com/outcoldman/Framework под эту платформу. И удачно реализовал gMusicW на нем (http://apps.microsoft.com/windows/en-us/app/gmusicw/939f0859-1413-4a52-9ab6-6e50405c8c2e). Но в итоге из-за нехватки времени просто стал контрибютить дальше только для gMusicW. Но в целом, Framework может показать пару интересных идей.
0
Не могли бы вы взглянуть на bitbucket.org/igor_kostromin/wpf-mvp/ (ссылка на пример)? Интересно ваше мнение о такой реализации — похоже, что у нас и получился именно MVPVM, о котором вы говорите.
0
Мне кажется в описании View-Model вкралась ошибочка в последнем пункте. Вполне возможно и даже принято связывать одну View-модель с несколькими View. Очень распространено в master-details представлениях.
+1
Не совсем понятно, а не приведет ли это к чрезмерному разрастанию View-модели, которая станет поистине универсальной и огромной, «на все случае (виды) жизни»?
В классическом описании модель может представлять себе один экземпляр.
В классическом описании модель может представлять себе один экземпляр.
0
Все зависит от программиста, но такого ограничения ни физически, ни логически нет. Для примера возьмем упомянутый паттерн master-details & WPF. Создаем в мастере список view-моделей, привязываем его к лист-боксу и задаем отображение для элемента. Это первое view для нашей view-модели. Далее создаем ContentControl и привязываем наш список с заключительным слешем (кто не знает, это привязывает выбранный элемент списка). Создаем отображение details для той же view-модели. Это будет второе view. Есть примеры отображения модели как графика и как списка или разных графиков и много другого разного. Главное, что идея MVVM не ограничивает привязку одного отображения.
0
UFO just landed and posted this here
Таких частных случаев как пионеров нерезанных. Я привел самый распространенный, без которого не обходится ни одна аппликация. Кстати Майкрософт по этому поводу говорит следующее: «There is typically a one-to-one relationship between a view and its view model». Другими словами это типично, но не обязательно. Пруфлинк msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx.
0
MVC, это не паттерн — это парадигма.
При MVC пользователь взаимодействует с Controller а не со View
При MVC пользователь взаимодействует с Controller а не со View
+2
Не ясно, что такое View в этом случае… Позвольте утверждать, что аббревиатурой MVC обычно понимают целое семейство паттернов, среди которых можно выделить первоначальный вариант.
0
www.itu.dk/courses/VOP/E2005/VOP2005E/8_mvc_krasner_and_pope.pdf
К тому же нужно разобраться в терминах, что есть шаблон. а что есть парадигма.
Но так как вы выделили, что:
уже говорит о том что вы подразумеваете парадигму.
К тому же нужно разобраться в терминах, что есть шаблон. а что есть парадигма.
Но так как вы выделили, что:
что аббревиатурой MVC обычно понимают целое семейство паттернов
уже говорит о том что вы подразумеваете парадигму.
0
Я могу ошибаться, но вроде как парадигма это совокупность действий, определяющих стиль. Т.е. парадигма в программровании — это семейство нотаций, различающихся по методикам. Примеры:
1. Функциональное программирование
2.Логическое программирование
3. ООП.
С другой стороны, Вы правы, в классическом MVC действия пользователя передаются в контроллер. Наверное, это имелось ввиду.
1. Функциональное программирование
2.Логическое программирование
3. ООП.
С другой стороны, Вы правы, в классическом MVC действия пользователя передаются в контроллер. Наверное, это имелось ввиду.
0
Я могу ошибаться, но вроде как парадигма это совокупность действий, определяющих стиль. Т.е. парадигма в программровании — это семейство нотаций, различающихся по методикам.
Вы правы, так оно и есть.
MVC — это парадигма, в которую вписываются семейство паттернов. Паттерн — это реализация и они различны, как вы сказали ранее (М.Фаулер о MVC)
0
Спасибо за статью.
Вопрос: как практически реализовать MVPVM в Windows Forms?
Сейчас у меня есть классы, в которых реализована логика и хранятся данные, есть формы в которых реализован интерфейс, в классе формы есть ссылка на экземпляр класса логики/данных и дальше происходит следующее:
когда мне нужно выполнить действие, то я ловлю событие нажатия на кнопку, метод обработки события сначала собирает данные из контролов формы, обновляет состояние класса логики и вызывает метод класса логики, затем обновляет интерфейсные контролы.
А как можно улучшить структуру?
Вопрос: как практически реализовать MVPVM в Windows Forms?
Сейчас у меня есть классы, в которых реализована логика и хранятся данные, есть формы в которых реализован интерфейс, в классе формы есть ссылка на экземпляр класса логики/данных и дальше происходит следующее:
когда мне нужно выполнить действие, то я ловлю событие нажатия на кнопку, метод обработки события сначала собирает данные из контролов формы, обновляет состояние класса логики и вызывает метод класса логики, затем обновляет интерфейсные контролы.
А как можно улучшить структуру?
0
Добрый день,
> когда мне нужно выполнить действие, то я ловлю событие нажатия на кнопку, метод обработки события сначала собирает данные из контролов формы, обновляет состояние класса логики и вызывает метод класса логики, затем обновляет интерфейсные контролы.
Вы описали логику Presentera. В Вашем случае, для практики, я бы рекомендовал обратиться к использованию паттерна MVP,
> когда мне нужно выполнить действие, то я ловлю событие нажатия на кнопку, метод обработки события сначала собирает данные из контролов формы, обновляет состояние класса логики и вызывает метод класса логики, затем обновляет интерфейсные контролы.
Вы описали логику Presentera. В Вашем случае, для практики, я бы рекомендовал обратиться к использованию паттерна MVP,
0
Несколько некорректно выглядит вот это утверждение об MVC: "Модель использует событие о том что она изменилась, и все подписанные на это события Представления, получив его, обращаются к Модели за обновленными данными, после чего их и отображают" в связке с указанием о том, что этот подход применяется в ASP.NET MVC. Конкретно там View не подписывается на изменения модели и никак не следит за ними. Эта роль отводится контроллеру, он реагирует на действие пользователя, меняет модель и отдает View измененные данные для отображения.
0
Мне одному кажется, что статьи про архитектуру ПО сильно проигрывают, если не дополнены примерами кода?
+1
UFO just landed and posted this here
Не вижу в этом вообще никакой проблемы. Среднестистический девелопер в команде постоянно работает с такими колоссальными объемами кода, на фоне которых примеры реализации архитектурных паттернов — капля в море. Тем более их всегда можно залить на гитхаб или спрятать под спойлер.
Вот пример статьи уважаемого мной товарища про модули в Java Script habrahabr.ru/post/181536/. Статья большая? Большая. Стало от этого хуже? Нет, не стало, статья замечательная и отвечает на 90% вопросов, связанных с паттернами модулей в Java Script.
Вот пример статьи уважаемого мной товарища про модули в Java Script habrahabr.ru/post/181536/. Статья большая? Большая. Стало от этого хуже? Нет, не стало, статья замечательная и отвечает на 90% вопросов, связанных с паттернами модулей в Java Script.
0
А как предотвратить лишние обновления Представления, если приходят повторяющиеся события об изменении данных в процессе пересчета Модели?
0
Видимо тут все сильно зависит от платформы. Если это XAML технология построенная на Bindings (XAML, Angular) то там представление обновится только тогда, когда данные реально поменяются.
В противном случае можно представление разбивать на более мелкие и обновлять только их.
В противном случае можно представление разбивать на более мелкие и обновлять только их.
0
Спасибо за ответ. Только не очень понятно про разбитие представления. Можно, я попробую описать пару проблемных примеров.
Пример 1. На форме в виде текстового поля нужно отобразить протокол выполняемых в Модели действий. Каждое действие в модели добавляет к тексту новую строку — и Модель каждый раз будет уведомлять представление, а представление каждый раз перерисовывать контрол с текстом.
Пример 2. Модель рассчитывает итоговую сумму, в которой суммируются другие расчетные значения, общее количество которых в начале расчета неизвестно. К примеру, в страховая премия складывается из выбранных пунктов договора страхования. Сначала мы обнуляем итоговую сумму, а затем рассчитываем нужные пункты и добавляем к итоговой сумме. И каждый раз, когда меняется итоговая сумма, от модели в представление будет идти событие об изменении и итоговая сумма будет перерисовываться в представлении.
Как избежать этих перерисовываний в обоих примерах? По идее модель должна уведомить представление только один раз — после всех расчетов, а представление отобразит окончательное значение один раз. Но как в модели определить, что именно это изменение будет последним? Ведь любая модификация данных может либо стать последней в алгоритме, либо за ней последуют другие модификации. В какой момент модель должна отправить сообщение представлению?
Как при связывании данных решается эта проблема?
Пример 1. На форме в виде текстового поля нужно отобразить протокол выполняемых в Модели действий. Каждое действие в модели добавляет к тексту новую строку — и Модель каждый раз будет уведомлять представление, а представление каждый раз перерисовывать контрол с текстом.
Пример 2. Модель рассчитывает итоговую сумму, в которой суммируются другие расчетные значения, общее количество которых в начале расчета неизвестно. К примеру, в страховая премия складывается из выбранных пунктов договора страхования. Сначала мы обнуляем итоговую сумму, а затем рассчитываем нужные пункты и добавляем к итоговой сумме. И каждый раз, когда меняется итоговая сумма, от модели в представление будет идти событие об изменении и итоговая сумма будет перерисовываться в представлении.
Как избежать этих перерисовываний в обоих примерах? По идее модель должна уведомить представление только один раз — после всех расчетов, а представление отобразит окончательное значение один раз. Но как в модели определить, что именно это изменение будет последним? Ведь любая модификация данных может либо стать последней в алгоритме, либо за ней последуют другие модификации. В какой момент модель должна отправить сообщение представлению?
Как при связывании данных решается эта проблема?
0
0
А без задержки никак нельзя?
0
Если хочется сэкономить пару перерисовок, можно не заниматься преждевременной оптимизацией, и оставить всё, как есть.
В некоторых фреймворках, например Angular, изменение модели на вид никак не влияет, фреймворк сам решает, когда перечитать модель, и такие оптимизации не понадобятся.
В примере 1, если одно действие пользователя вызовет добавление десятков строк в лог, а сама модель за лог не отвечает, задержка будет неплохим вариантом. Если лог генерируется в UI-потоке, можно поставить задержку в 1 мс, что по факту приведёт к 1 перерисовке сразу после завершения вычислений и освобождения UI-потока. Задержки по полсекунды нужны для других случаев, например, когда ввод текста пользователем вызывает отправку запросов на сервер (поисковые подсказки и т.д.).
В примере 2, результатом расчётов, видимо, является одно значение, вот пусть модель его и считает, а результат передаёт в модель вида, только когда он готов. Разделение на M и VM нужно, в том числе, и для этого.
В некоторых фреймворках, например Angular, изменение модели на вид никак не влияет, фреймворк сам решает, когда перечитать модель, и такие оптимизации не понадобятся.
В примере 1, если одно действие пользователя вызовет добавление десятков строк в лог, а сама модель за лог не отвечает, задержка будет неплохим вариантом. Если лог генерируется в UI-потоке, можно поставить задержку в 1 мс, что по факту приведёт к 1 перерисовке сразу после завершения вычислений и освобождения UI-потока. Задержки по полсекунды нужны для других случаев, например, когда ввод текста пользователем вызывает отправку запросов на сервер (поисковые подсказки и т.д.).
В примере 2, результатом расчётов, видимо, является одно значение, вот пусть модель его и считает, а результат передаёт в модель вида, только когда он готов. Разделение на M и VM нужно, в том числе, и для этого.
0
Спасибо за разъяснения. Посмотрел про Angular — там красивые уроки и примеры. Получается, что в этом фреймворке модель пассивная и сама не отправляет сообщения. Как же все-таки Angular определяет, что именно в $scope изменилось в модели по сравнению с предыдущей версией?
0
На то или иное изменение во view вызывается метод $scope.$apply, например (цитата из angular.js, код стандартного обработчика для checkbox'а):
$scope.$apply() в своем коде вызывает $scope.$digest (см. исходный код).
При этом у $scope'а есть свойство $$watchers — это функции, которые по вызову вычисляют какое-то определенное для каждой из них выражение (первый аргумент), и если оно поменялось с момента предыдущего вызова, вызывают callback (второй аргумент) [ссылка на синтаксис создания $watcher'а. В большинстве случаев эти штуки добавляются встроенными директивами].
$scope.$digest() вызывает все $scope.$$watchers по очереди, сравнивая старое и новое значение выражений для каждого из них (см. тело функции $digest) и, если старое и новое значения для данного $watcher'а различаются, запускается callback соответствующего $watcher'а, принимающего oldValue и newValue в качестве аргументов.
Соответственно уже конкретный callback может делать что угодно — менять какое-то другое выражение, добавлять/менять/убирать разметку определенного элемента и т.п.
Как-то так)
...
element.on('click', function() {
scope.$apply(function() {
ctrl.$setViewValue(element[0].checked);
});
});
...
$scope.$apply() в своем коде вызывает $scope.$digest (см. исходный код).
При этом у $scope'а есть свойство $$watchers — это функции, которые по вызову вычисляют какое-то определенное для каждой из них выражение (первый аргумент), и если оно поменялось с момента предыдущего вызова, вызывают callback (второй аргумент) [ссылка на синтаксис создания $watcher'а. В большинстве случаев эти штуки добавляются встроенными директивами].
$scope.$digest() вызывает все $scope.$$watchers по очереди, сравнивая старое и новое значение выражений для каждого из них (см. тело функции $digest) и, если старое и новое значения для данного $watcher'а различаются, запускается callback соответствующего $watcher'а, принимающего oldValue и newValue в качестве аргументов.
Соответственно уже конкретный callback может делать что угодно — менять какое-то другое выражение, добавлять/менять/убирать разметку определенного элемента и т.п.
Как-то так)
0
В последнее время на Хабре, да и в принципе в головах разработчиков так часто мусолится тема MVC/MVP/MVVM/MV*, начало всплывать такое множество различных вариаций этих паттернов, что в какой-то момент задумываешься: а где же, блин, отличия между ними :-) Приходится (зачем?) глубоко вчитываться во все описания и приходить к выводу, что всё это многообразие обусловлено лишь ограничениями\спецификой случаев, в которых их применяют. И «толщиной» каждого из слоёв — где-то больше кода во вью, где-то в контроллере. Как результат — когда кто-то рассказывает тебе о MV* или задаёт тебе вопрос на эту тему, уже невольно теряешься: а что конкретно этот человек понимает под этими буквами. Все эти различия и нюансы настолько незначительны и не принципиальны…
0
Добрый день,
Позвольте не согласиться с Вашим последним утверждением. Различия и нюансы сильно влияют на дальнейшее развитие продукта в целом.
На мой взгляд, применение определенной архитектуры — это стратегия развития продукта, его возможностей в будущем. Например, через 2-3 релиза, учитывая, что у нас RUP.
Позвольте не согласиться с Вашим последним утверждением. Различия и нюансы сильно влияют на дальнейшее развитие продукта в целом.
На мой взгляд, применение определенной архитектуры — это стратегия развития продукта, его возможностей в будущем. Например, через 2-3 релиза, учитывая, что у нас RUP.
+1
Я пытался сказать, что в теории, статьях, картинках, разговорах — различия между паттернами высосаны из пальца и не принципиальны. Мало смысла пытаться забивать себе голову тем, как MVC отличается от, допустим, MVPVM. На практике разница будет, но не в принципиальном подходе, а небольших деталях реализации. И вытекать она будет из требований и условий проекта, а не решений сверху «давайте здесь будет использовать MVP, а вот здесь — MVVM». И всё-равно в каждом проекте будет своя «версия» MV*, отличающаяся от теории. Даже в пресловутом ASP.NET MVC не то, что описано в данной статье.
0
Спасибо за статью, Сергей!
В секции Model-View-Controller в качестве признака Контроллера указан пункт «Контроллер определяет, какие представление должно быть отображено в данный момент;», однако на прикрепленной вами диаграмме не указана определяющая связь от Контроллера к Представлению. Скорее, указана определяющая связь от Представления к Контроллеру. Я правильно понимаю, что это противоречие?
Возможно, вы имели в виду что-то вроде www.sitepoint.com/getting-started-with-mvc с диаграммой
В этой диаграмме действительно показана определяющая роль Контроллера при выборе Представления.
Также должен сказать, что в ряде обучающих статей на тему (например, в Википедии ru.wikipedia.org/wiki/Model-View-Controller) действия пользователя передаются не в Представление, а в Контроллер. Но тут стоит сказать, что общее несоответствие в этой детали по поводу MVC мы можем наблюдать во всех статьях по теме.
В секции Model-View-Controller в качестве признака Контроллера указан пункт «Контроллер определяет, какие представление должно быть отображено в данный момент;», однако на прикрепленной вами диаграмме не указана определяющая связь от Контроллера к Представлению. Скорее, указана определяющая связь от Представления к Контроллеру. Я правильно понимаю, что это противоречие?
Возможно, вы имели в виду что-то вроде www.sitepoint.com/getting-started-with-mvc с диаграммой
В этой диаграмме действительно показана определяющая роль Контроллера при выборе Представления.
Также должен сказать, что в ряде обучающих статей на тему (например, в Википедии ru.wikipedia.org/wiki/Model-View-Controller) действия пользователя передаются не в Представление, а в Контроллер. Но тут стоит сказать, что общее несоответствие в этой детали по поводу MVC мы можем наблюдать во всех статьях по теме.
0
Sign up to leave a comment.
Articles
Change theme settings
Паттерны для новичков: MVC vs MVP vs MVVM