Model View ViewModel, Модель Вид Модель Вида, Unity, C#
HTML-код
- Опубликовано: 28 июн 2024
- Пожалуй, паттерн на который я потратил больше всего времени
p.s. Забыл про отписку от OnChanged в примерах, в гитхаб залью правку
Гитхаб на проект с демкой из видео: github.com/Haywaar/PatternDem...
Лежит по пути
Assets/Patterns/MVVMExample_Simple - окно прокачки персонажа
Assets/Patterns/MVVMExample - слот машина с режимом реролла
Ссылка на UniRx
github.com/neuecc/UniRx
assetstore.unity.com/packages...
Автору на кофе и шаурму
4276 5500 5792 8742 - карта Сбербанка
Если будут вопросы
мой тг @wargy
моя почта kazancev.s215@gmail.com
Тайминги:
00:00 Введение
00:29 Паттерны MV*-семейства
00:58 История появления MVVM
04:45 Определение MVVM
06:13 Что такое ViewModel?
07:31 Что такое DataBinding?
08:51 DataBinding в Unity
10:24 Схема ролей MVVM
11:40 UML схема MVVM
12:28 Конкретный пример: введение
13:54 Конкретный пример: пишем Model
14:40 Конкретный пример: пишем ViewModel
16:14 Конкретный пример: пишем View
17:26 Когда использовать MVVM?
18:44 Реактивное программирование?
20:36 Финал Игры
Небольшое уточнение для пары классных ребят-занудок типа меня по историческому ликбезу.
В своей статье про Presentation Model Мартин Фаулер тоже говорил о дата-биндинге как о взаимодействии между View и Presentation Model.
Цитирую с martinfowler.com/eaaDev/PresentationModel.html
"Probably the most annoying part of Presentation Model is the synchronization between Presentation Model and view. It's simple code to write, but I always like to minimize this kind of boring repetitive code. Ideally some kind of framework could handle this, which I'm hoping will happen some day with technologies like .NET's data binding."
То есть - "было бы неплохо прикрутить дата биндинг, но пока такого решения нет, надеюсь .Net когда то до этого дойдет"
Джон Госсман же перенёс эту идею в Microsoft, и реализовал её как стандарт для WPF и Silverlight архитектур.
Статья learn.microsoft.com/en-us/archive/msdn-magazine/2009/february/patterns-wpf-apps-with-the-model-view-viewmodel-design-pattern
И сам текст
MVVM is identical to Fowler's Presentation Model, in that both patterns feature an abstraction of a View, which contains a View's state and behavior. Fowler introduced Presentation Model as a means of creating a UI platform-independent abstraction of a View, whereas Gossman introduced MVVM as a standardized way to leverage core features of WPF to simplify the creation of user interfaces. In that sense, I consider MVVM to be a specialization of the more general PM pattern, tailor-made for the WPF and Silverlight platforms.
Получается MVVM это тот же самый PM Фаулера только доточенный под микрософтовский фреймворк 😕 Почему тогда паттерн называется MVVM а не PM ибо PM более общая архитектура, а MVVM частное решение - непонятно. Но, так исторически сложилось
Благодарю за ролик, объясняете лучше чем те у кого миллионы просмотров, только после ваших видео четко понял концепции архитектур)
Было бы интересно послушать про то как правильно выстраивать общую архитектуру игр, в особенности сетевых
Если интересует Сервер-Клиент, то советую поискать где-нибудь в сети старые билды игры Rust, года 2017-2019. Тогда dll’ки юнити легко декомпилировались. Я полностью пересобрал эту игру у себя. Почерпнул просто гигантские знания, особенно если учитывать, что когда я начинал изучать исходники, то был практически полным новичком в программировании.
На канале есть рубрика паттерны на практике, где я делаю небольшие игры и выкладываю их в открытый доступ на гитхаб. На видео в этой рубрике я точечно разбираю какие решения я использую и тд, может вам будет полезно
Как же вы классно и наглядно обьясняете, спасибо за ваш труд и качественный контент!
Как я проорал с мема "Это тяжелее , чем Singleton". Спасибо за видео!
Воу, это очень круто! Впервые на этом канале и это прям топ. Очень крутой продакшен и уровень программирования что очень редко для ру сегмента, так что спасибо автор!
Как всегда отлично! Все четко и по полочкам.
Отличный ролик, лаконично, с качественными примерами и хорошей аналитикой
Отличная подача! Отличные слайды! Все по делу
Очень полезно и понятно. Спасибо за твою работу!
Спасибо, очень хорошо объяснено!
Молюсь что бы канал не забросился
Помолитесь, пожалуйста, чтобы я работу нашёл, а то попал тут под сокращение в Европе и полтора месяца ничего найти не могу :D
Главное при всем этом не забывать отписываться от подписок перед уничтожением объекта. А то память потечет
Да, забыл об этом, спасибо)
я хз, эти вставки просто имба - мемы в точку!))
Отлично преподносишь материал, я все видео просматриваю и на заметку себе много интересного заключаю, если есть желание про ECS и Zenject было бы отлично
Ох уж этот Zenject и ECS ))) постараюсь в ближайшие пару месяцев до зенжекта добраться)
Очередной бэннгер от моего любимого сэнсея.
Ого, такой точной подачи материала еще не видел, программирую всего пол года, но с трудом все понимаю
С трудом все понимать это нормально, я работаю программистом уже 7 лет, но не могу сказать, что все знаю и легко все осваивается) главное, продолжать развиваться)
Круто!
Отличное видео, спасибо большое. Единственное замечание: то, что ты описал в unity, это не MVVM, а PresentationModel в чистом виде. При реализации MVVM дата-биндингом занимается отдельный фреймворк (например, unity weld), а так как всю синхронизацию пришлось писать самому ручками - то по Фаулеру это чистая PM.
Спасибо за комментарий! Хорошее замечание, только сейчас заметил что Фаулер в конце описания PM так тихонечко упомянул что хорошо бы прикрутить Data-binding , хоть в конце статьи написал неплохое разъяснение. А Госсман получается о Data-Binding-е чуть громче говорил и говорил что он прям НУЖЕН.
Получается если DB есть и в PM и в MVVM то тогда никакой архитектурной разницы для юнитологов между ними нет, потому то мы не делаем приложения в WPF
Скинул 500 рублей на Сбербанк за годный контент! Спасибо за работу!
Принял, спасибо большое за поддержку)
Имхо, дело вкуса использовать ли в небольших проектах этот паттерн или нет. По мне, так лучше больше простых простыней из кода, но при этом четкая шаблонная структура, в которой очень сложно запутаться, чем меньше кода, но неорганизованный подход. Тем более что очень часто бывает такое, что небольшой по изначальному замыслу проект начинает разрастаться и клубок запутывается все сильнее и сильнее. Было бы круто конечно запилить в Юнити подобие биндинга из WPF.
Само видео отличное, большое спасибо за него. Теперь в самой сути паттерна наконец то разобрался.
Имхо, не дело вкуса. Потому что MVP, MVVM и тд решают похожие, но разые проблемы. Тут скорее зависит от того, какая у тебя проблема в проекте, которую надо решить. Очевидно, что если у тебя есть только консольный вывод и не планируется другой, то городить код не имеет смысла. И совсем другой кейс, когда ты делаешь приложение и сейчас у тебя простой UI, но UX-дизайнер, продюсер и ГД говорят тебе, что в будущем многие окна будут чуть не ли не отдельным мини-приложением.
К слову про мультиплеер и сложные проекты. Обычно под капотом там простая логика, классы зависят от абстракций и интерфейсов, а модули по типу View внутри себя разбиты еще на компоненты, каждый при этом автономен. Вот и получается, что с Вьюшки уходит инпут на Presenter, который отправляет условную команду перетащить предмет инвентаря на другой слот, с Presenter идут запрос на модель, по сути на бек, и обратно возвращается по цепочке, обновляя UI у клиента в конечном итоге. А это обычный MVP. Делал раньше нечто похожее на MVVM, но мне это показалось оверхедом, т.е. все становится слишком абстрактным, и по сути ViewModel ничего не делает а просто осуществляет перекрестную подписку. Это скорее местечковое решение, чтобы просто работало, нежели правило для всех сложных проектов. И я бы такое использовал только в случае где без этого никак не обойтись. Это скорее усложняет структурированную логику MVP, добавляя перекрестные события и промежуточные стейты для View во ViewModel. имхо
Мемы смешные
Для меня тоже довольно потный паттерн для понимая.
Знаю еще, что в Plarium игра "Raid Shadow Legends" отказалась от MVVM в пользу MVP. Вроде бы большой проект, но MVVM оказался слишком громоздким и сложным для работы с ним и потом всё переписывали.
То-есть весь прикол в том, что паттерн который подходит для больших проектов иногда к ним же подходит хуже всего.
+ Если шаришь MVP, то можно и прошарить логику работы ECS, там принцип работы построенный на данных, а это по-сути наш Model.
Насколько я знаю в Hustle Castle MVVM довольно плотно используется, видел видео с TBD Pro.
Как раз сейчас пытаюсь для видосиков запилить вторую игру и на MVVM построить несколько диалогов с прокачкой и инвентарём персонажа. Посмотрим что из этого выйдет
А на счёт разделения слоёв, да тут по идее любой MV* паттерн должен подойти но MVVM с его состояниями не так удобен для ECS-а судя по всему. С другой стороны а как иначе хранить эти состояния?
Отличное видео, спасибо! Попробовал сам повторить в своем проекте - очень круто получилось по сравнению с тем что было!
Вопросик небольшой, а есть какое-то готовое решение, которое позволит использовать MVVM в Unity так же как в WPF?)) Ну то есть где уже вшито ReactiveProperty и явные подписки задавать было бы необязательно) Просто странно, что Юнити столько лет, а мы всё еще не имеем какого-то архитектурного паттерна встроенного...
Есть UniRx, ссылка на него есть в описании, но там немного другой подход к написанию кода. О других нормальных решениях я не знаю, возможно, где-то есть, сколько видел, люди либо писали на UniRx, либо писали своё
@@sergeykazantsev1655, UniRx обязательно попробую) тебе спасибо и процветания каналу!
Посмотри в сторону Unity Weld
@@alexsorokin8373 Погуглите "MVVM Hustle Castle". Там разработчик говорил, что решили не прикручивать UniRx потому что он слишком тяжелый. Ну и может, что почерпнете интересного еще.
нативный андроид наше всё))0
К примеру вьюшка главного меню, что-то пишем в модель, для сохранения, что-то просто как стейт во вьюмодели крутится. А если нужен сервис, к примеру загрузить некст сцену? Его во ВьюМодел загонять и делать доступ через метод для вьюхи?
Если я правильно вас понял, то да. Как и в mvc, mvp так и в mvvm может быть какая-то логика. Сервис по идее тоже можно засунуть во viewmodel
Кстати, между делом говоря есть еще паттерны HMC, HMVP. Компания Playtika о них написала пару статей.
У меня появился вопрос. Во всех паттернах группы MV* мы живём с зависимостями, например: View -> ViewModel.
А используется ли к ним DI? Потому что в примерах их нет. Отчасти я понимаю, что это может быть для упрощения. Однако, я не пойму как его можно было бы использовать в них.
Не сделаешь же по сути никакой интерфейс с Модели или Вида, чтобы потом можно было его инжектить. С другой стороны не лучше ли тогда инжектить сразу целый класс, но всё равно через DI контейнер?
Спасибо за видео.
Мне кажется можно DI спокойно использовать. В примерах я вроде даже делал абстрактный класс View, ViewModel и Model, а потом уже от этих абстрактных классов ты наследуешься, то есть по факту работаешь на уровне интерфейса.
Таким образом в DI-контейнер мы прокидываем не конкретную реализацию модели или вьюмодели а через абстрактный класс
Я правда когда пробовал так - всё равно столкнулся с тем, что сильно ты с разной реализацией не разойдешься, потому что model-viewModel-view даже если на уровне абстракций, но завязаны друг на друга.
Если сделать новую реализацию модели с новым полем, то надо и по идее новую вьюмодель писать чтобы это новое поле обрабатывалось, что очень неудобно.
@@sergeykazantsev1655 Вот поэтому я и не уверен, что здесь стоит DI использовать.
По-логике DI должен упрощать код и делать его более гибким, но прикол MVP, MVC, MVVM, что они сами по себе гибкие и как по мне в DI не нуждаються, а добавишь, то только усложнишь логику.
@@sergeykazantsev1655 Я чекну. На польском есть пара презентаций как их сочетать. После просмотра отпишу.
А чья зона ответственности выбирать какую view и/или viewModel спавнить?
их надо "склеивать" где-то выше уровнем. То есть где-то будет скрипт в который вы прокидываете конфиги и который будет принимать это решение
А как быть, если StatsViewModel не может только по значениям из StatsView определить новые данные PlayerModel? (значения PlayerModel определяются из вереницы методов других объектов) Ему нужно создать клона playermodel. То есть толку что в statsview чтото меняется, если нужно знать конечные характеристики при изменении statsview.
StatsViewModel не обязан собой полностью покрывать все данные PlayerModel.
По коду я с таким не сталкивался но мне кажется что вполне реально на одну большую модель сделать 3 разных viewModel и view.
Условно отдельный viewModel для статов и её изменения + отдельный ViewModel для шмоток + отдельный для личной инфы.
Тогда получается что клон не нужен, а наоборот на одну и ту же модель будет завязано 3 вьюмодели, каждая из которых отвечает за своё.
ViewModel нарушает SPR?
По самой архитектуре MVVM - я думаю, что нарушает ибо
Есть зона ответственности - обработка сигналов со стороны пользователя
Есть зона ответственности - мониторинг изменения модели
Есть зона ответственности - хранение состояния UI(те самые режимы)
теоретически эти зоны ответственности можно запихнуть во внутренние скрипты
как я уже говорил, MVVM в малой степени использует ключевые принципы ООП(ни наследования, ни программирования на уровне интерфейса, ни инкапсуляции как таковой), и больше перетекает в реактивное программирование
А вы знаете что такое абстрактный класс и для чего он предназначен? Я конечно понимаю что это просто пример, можете объяснить для чего ViewModel и View в данном случае помечены как абстрактные? Ведь они реализуют логику конкретного элемента интерфейса и никакой абстракцией тут и не пахнет
Хочу сразу добавить что само видео мне понравилось, хорошее и понятное объяснение подхода и его отличия от MVP.
ViewModel и View помечены как абстрактные на случай если у вас должны быть разные реализации. Например у вам может быть MobileAppView и DesktopPCView, они будут иметь разную внутреннюю логику.
Если в базе стоит абстрактный класс вы можете комбинировать разные реализации Model, View и ViewModel
@@sergeykazantsev1655 теперь понятно, меня смутил нейминг))