Смотря на что фокусироваться. Может, что как раз наоборот) Модель — простая, VM — автоматом делается, а вот интерфейс попробуй нарисуй, чтобы красивый был, интуитивный, удобный, эргономичный и т.д.
Эти две фразы неверны. VM не зависит от View, а наоборот. Это позволяет использовать VM с разными View.
Я использую две методики написания программ в MVVM: 1.Model first 2. View first
В обоих VM разрабатывается после View.
Про модель в вакууме — значит, что она не зависит от VM и View, и ничего про них не знает. У нею своя атмосфера.
Это не так. В VM у нас может быть один объект и это могут быть его свойства
…
Биндинги в WPF — это нечто прямо противоположное «железному прибитию»
Не придирайтесь. Я имею ввиду, что сколько во вью открыто «слотов» для биндинга, столько должно ему предоставлять VM. А под словом «железно» имеется ввиду, что VM это не нечто, как модель — абстрактное в вакууме, а такое нечто, что зависит от вью, имеет открытых «слотов» столько, чтобы удовлетворить свою View
… инкапсуляция — это не принцип, а механизм
Инкапсуляция — это как раз принцип. А уж как именно вы инкапсулируете — это механизм.
Увы, нет. Мы не «пробрасываем свойства», мы используем один из плохих приёмов программирования — программирование по совпадению…
В статье акцент сделан в первую очередь на MVVM, а это удобная конструкция, избавляющая от необходимости прописывать каждое пробрасываемое свойство из модели. В реальных проектах такое не прокатывает и чревато — это понятно.
… считаю, что проверка на валидность того, что вводит пользователь — обязанность View..
Имелось ввиду валидация в конкретном случае. Вообще же — валидация сначала во View (уже даже самим типом контрола — используя RadioButton сложно ввести невалидное значение). Если нельзя во вью, то в VM. Если нельзя в VM, то задействуем Модель.
ShowSomeWindowCommand = new DelegateCommand<Window>(own =>
{
//someVar и anotherVar используются в конструкторе SomeWindow, чтобы создать себе VM
var dlg = new SomeWindow(someVar, anotherVar) {Owner = own};
var result = dlg.ShowDialog();
...
});
В качестве CommandParameter передаю родительское window.
Так вот как раз у этих «умельцев», несмотря на пустой код-бехайнд, — MVVM не чистый, а разбавленный )
А так — вполне согласен, что код-бехайнд может содержать код, если его наличие/отсутствие никак не сказывается на модели.
Где же быть логике, как не в модели? О_0 Бизнес-логика она в модели. DAL я трактую, как бедные репозитории, просто доступ к данным, но логика- дожна быть отдельно.
Конечно сложение чисел с МВВМ — это оверкил, но позволяет сосредоточится на теории, не загромождая все реализацией. К тому же это не последний пример
Логика вьюхи? Если имеется ввиду всякие IsVisible, IsEnabled — то в VM.
Если всякие украшательства, типа анимации — то в XAMLe. Если в XAML они не лезут, то тогда в код бехайнд.
Чистый MVVM значит, что можно миксовать MVVM и MVP. Хотя можно с помощью windows.interactivity попытаться оставаться в рамках MVVM, но если программа сильно «вьюхоцентричная», то можно создать интерфейс вьюшки и вызывать его.
Хм, интересно) И при невыставленном DataContext работает такое использование регулярных свойств в качестве соурса биндинга.
На мой взгляд то, где будет VM физически — это незначимая деталь реализации. Но можно дать такой ответ:
В вашей конструкции при биндинге надо всякий раз указывать имя элемента управления, и второе: неясно, что делать, в случае нескольких View на один VM.
2. Не чаще всего code behind останется пустым, а всегда будет оставаться пустым, если используется чистый MVVM.
Одна VM для нескольких вьюшек используется, не столько для того, чтобы расшарить контекст, а скорее для того, чтобы разбить вью на физические части, а потом скомпоновать в общей вьюшке. Просто View в XAMLе могут быть достаточно… громоздкими, аляповатыми, знаете, со всеми этими <Grid.RowDefinitions>… да и вообще, как любой XMLобразный код.
В вашем примере с привязками вы биндитесь к DependencyProperty, в случае же использования DataContext подойдут регулярные свойства. Они по объему кода гораздо скромнее
1. Так вопрос в чем преимущество MVVM над MVP или MVC?
Ну, вот конкретно в WPF в том, что MVVM «аппаратно» поддерживается WPF. View понимает и INotifyPropertyChange, и Observable и др. — ее не надо руками обновлять через презентер. Интерфейс вьюшки городить не надо. Биндинг в конце-концов. Мне MVP в WinForms'ах не нравился тем, что уж очень там много руками делать приходилось.
Два вопроса вижу:
1. Для чего MVVM? Отвечаю: для того, чтобы у вас была самодостаточная модель, сгруппированная в одном месте. Чтобы была отделена от инфраструктурного кода. Если, условно, инфраструктурный код — это 70%(и больше) от всего кода, а бизнес-логика — 30% — то очень хорошо эту модель иметь в одном месте, а не размазанную по обработчикам событий кучи контролов. Тогда модель поддается тестированию, изменению функционала, она компактнее, понятнее и т.д. Всегда можно взять модель и написать совершенно другой инфраструктурный код, для другой платформы, другой библиотеки и т.д.
2. Почему нельзя использовать кодбехайнд в качестве VM?
Отвечаю: никто не запрещает вам использовать кодбехайнд в качестве DataContext самого себя, но только в случае, если у вас на один View одна VM. Но часто бывает, что одна VM используется для многих View. Это удобно делать, чтобы не городить огромную вьюшку, а разбить ее на ряд вьюшек поменьше — их тогда и перекомпоновать будет проще. В таком случае нелогично использовать один контрол в качестве DataContext других контролов.
Ну, во-первых в вебе валидировать надо (и) на серверной стороне, конечно. Во-вторых в комментах про тестирование, а у вас мысль уже куда-то в сторону пошла
Проверку валидности ввода email можно организовать еще на этапе вьюшки, — есть data annotations, ErrorInfo и т.п. — такое проверять не надо. Если проверка комплексная, то выносим ее в модель, в какую-нибудь IsEntityValid, и там проверяем.
Просто есть идеальное видение, с полным покрытием кода, и есть реальный мир, где нередко программисты вообще не пишут юнит-тесты. Растеряв силы или заскучав на проверке VM, они могут и не добраться до модели, а так — пусть хоть модель покроют.
Совершенно верно: разделение ответственности в большой степени способствует повышению тестируемости. Т.е. когда мы выдираем модель из behind code обработчиков событий и собираем в одном месте — тестировать ее значительно легче. Вот, собственно, модель обычно и покрывают юнит-тестами. Например: в первом примере необходимо убедиться, а действительно ли статическая функция складывает два числа корректно…
Касательно покрытия тестами VM — этим обычно… ну, во всяком случае я, — не занимаются. Текст VM совершенно плоский. И вызовы делегатов из VM — тоже вполне планарны. А вот то, что они вызывают в модели — покрывать тестами действительно стоит.
Я использую две методики написания программ в MVVM: 1.Model first 2. View first
В обоих VM разрабатывается после View.
Про модель в вакууме — значит, что она не зависит от VM и View, и ничего про них не знает. У нею своя атмосфера.
Инкапсуляция — это как раз принцип. А уж как именно вы инкапсулируете — это механизм.В статье акцент сделан в первую очередь на MVVM, а это удобная конструкция, избавляющая от необходимости прописывать каждое пробрасываемое свойство из модели. В реальных проектах такое не прокатывает и чревато — это понятно.
Имелось ввиду валидация в конкретном случае. Вообще же — валидация сначала во View (уже даже самим типом контрола — используя RadioButton сложно ввести невалидное значение). Если нельзя во вью, то в VM. Если нельзя в VM, то задействуем Модель.
В качестве CommandParameter передаю родительское window.
А так — вполне согласен, что код-бехайнд может содержать код, если его наличие/отсутствие никак не сказывается на модели.
Конечно сложение чисел с МВВМ — это оверкил, но позволяет сосредоточится на теории, не загромождая все реализацией. К тому же это не последний пример
Если всякие украшательства, типа анимации — то в XAMLe. Если в XAML они не лезут, то тогда в код бехайнд.
Чистый MVVM значит, что можно миксовать MVVM и MVP. Хотя можно с помощью windows.interactivity попытаться оставаться в рамках MVVM, но если программа сильно «вьюхоцентричная», то можно создать интерфейс вьюшки и вызывать его.
На мой взгляд то, где будет VM физически — это незначимая деталь реализации. Но можно дать такой ответ:
В вашей конструкции при биндинге надо всякий раз указывать имя элемента управления, и второе: неясно, что делать, в случае нескольких View на один VM.
Одна VM для нескольких вьюшек используется, не столько для того, чтобы расшарить контекст, а скорее для того, чтобы разбить вью на физические части, а потом скомпоновать в общей вьюшке. Просто View в XAMLе могут быть достаточно… громоздкими, аляповатыми, знаете, со всеми этими <Grid.RowDefinitions>… да и вообще, как любой XMLобразный код.
В вашем примере с привязками вы биндитесь к DependencyProperty, в случае же использования DataContext подойдут регулярные свойства. Они по объему кода гораздо скромнее
Ну, вот конкретно в WPF в том, что MVVM «аппаратно» поддерживается WPF. View понимает и INotifyPropertyChange, и Observable и др. — ее не надо руками обновлять через презентер. Интерфейс вьюшки городить не надо. Биндинг в конце-концов. Мне MVP в WinForms'ах не нравился тем, что уж очень там много руками делать приходилось.
1. Для чего MVVM? Отвечаю: для того, чтобы у вас была самодостаточная модель, сгруппированная в одном месте. Чтобы была отделена от инфраструктурного кода. Если, условно, инфраструктурный код — это 70%(и больше) от всего кода, а бизнес-логика — 30% — то очень хорошо эту модель иметь в одном месте, а не размазанную по обработчикам событий кучи контролов. Тогда модель поддается тестированию, изменению функционала, она компактнее, понятнее и т.д. Всегда можно взять модель и написать совершенно другой инфраструктурный код, для другой платформы, другой библиотеки и т.д.
2. Почему нельзя использовать кодбехайнд в качестве VM?
Отвечаю: никто не запрещает вам использовать кодбехайнд в качестве DataContext самого себя, но только в случае, если у вас на один View одна VM. Но часто бывает, что одна VM используется для многих View. Это удобно делать, чтобы не городить огромную вьюшку, а разбить ее на ряд вьюшек поменьше — их тогда и перекомпоновать будет проще. В таком случае нелогично использовать один контрол в качестве DataContext других контролов.
Просто есть идеальное видение, с полным покрытием кода, и есть реальный мир, где нередко программисты вообще не пишут юнит-тесты. Растеряв силы или заскучав на проверке VM, они могут и не добраться до модели, а так — пусть хоть модель покроют.
Касательно покрытия тестами VM — этим обычно… ну, во всяком случае я, — не занимаются. Текст VM совершенно плоский. И вызовы делегатов из VM — тоже вполне планарны. А вот то, что они вызывают в модели — покрывать тестами действительно стоит.