MVVM vs. MVI - Understand the Difference Once and for All
Summary
TLDRВ этом видео сравниваются два популярных шаблона архитектуры приложений: MVVM и MVI. Автор объясняет, что оба шаблона предназначены для разделения представления, но не для всей приложения. Он демонстрирует, как реализовать каждый из шаблонов в Android, используя примеры кода и объясняя ключевые различия. В видео также упоминается бесплатный онлайн-семинар для Android-разработчиков, который будет посвящён основным практикам и архитектурным шаблонам. В заключение автор рекомендует попробовать оба шаблона и выбрать тот, который больше всего подходит для команды и проекта.
Takeaways
- 📚 В видео обсуждается различие между архитектурными шаблонами MVVM и MVI в разработке нативного Android.
- 🔍 MVVM (Model-View-ViewModel) и MVI (Model-View-Intent) являются представлениями шаблонов и используются для разделения представления слоя в приложении.
- 🏗️ Оба шаблона не предназначены для разделения всей приложения на части, а только для представления слоя, в отличие от Clean Architecture, который разделяет все приложение на слои.
- 📈 Важно понимать, что модель в обоих шаблонах отвечает за бизнес-логику и правила, часто представленные в виде обычных классов данных.
- 🎭 Представление (View) обозначает то, что видно пользователю, и может быть реализовано как XML-шаблоны, классы представлений или композиции Jetpack Compose.
- 🧐 ViewModel в MVVM и ViewModel в MVI оба отвечают за логику состояния, определяя, как должно выглядеть состояние после пользовательских действий.
- 🔑 Основное различие между MVVM и MVI заключается в использовании MVI(Intent) для группировки пользовательских намерений на экране в одно действие.
- 🤔 MVI использует единый класс состояния (UI State), в то время как MVVM может иметь множество полей состояния для разных компонентов UI.
- 🛠️ В MVI для обработки действий предоставляется функция onAction, что позволяет обрабатывать различные пользовательские намерения (например, переключение лайка).
- ⚠️ Критики MVI указывают на дополнительный слой (Intent) и возможные проблемы с производительностью при обновлении состояния, в отличие от MVVM.
- 📉 Несмотря на возможные недостатки, MVI считается более читаемым и простым в использовании, особенно для больших экранов с множеством состояний.
Q & A
Что означает аббревиатура MVVM в контексте разработки на Android?
-MVVM означает Model-View-ViewModel. Это архитектурный шаблон, используемый для разделения представления (View) и бизнес-логики (Model) с помощью ViewModel, который работает как связующий элемент между ними.
Какова разница между MVVM и MVI в разработке на Android?
-В MVI (Model-View-Intent), в отличие от MVVM, представление (View) отправляет 'намерения' (Intent) в ViewModel, который затем обрабатывает эти намерения и обновляет состояние. В MVVM состояние обновляется непосредственно в ViewModel в ответ на действия пользователя.
Почему разработчики иногда предпочитают MVVM перед MVI?
-Разработчики могут предпочесть MVVM из-за его простоты и того, что он предлагает прямую связь между действиями пользователя и изменениями состояния, что может быть проще для понимания и реализации.
Что такое 'намерение' (Intent) в контексте MVI?
-Намерение в MVI - это действие пользователя, которое представление (View) отправляет в ViewModel. Это может быть, например, нажатие кнопки или изменение текста в поле ввода.
Какие преимущества предлагает использование MVI в сравнении с MVVM?
-MVI может предоставить более чистую и понятную структуру кода благодаря группировке всех состояний в одном классе и использованию намерений для обработки действий пользователя.
Какие могут быть недостатки использования MVI?
-Одним из недостатков MVI может быть то, что при больших экранах может быть необходимо обрабатывать много различных намерений, что может усложнить код и сделать его менее читабельным.
Что такое ViewModel в Android и как он используется в MVVM и MVI?
-ViewModel в Android - это компонент, который хранит состояние приложения и используется для связи между моделью (Model) и представлением (View). В MVVM ViewModel обрабатывает действия и обновляет состояние, в то время как в MVI он обрабатывает намерения, отправленные View.
Какие типы данных используются для представления бизнес-правил и логики в модели MVVM и MVI?
-Для представления бизнес-правил и логики в модели MVVM и MVI обычно используются обычные классы данных (data classes), которые содержат информацию о том, какие данные и какая логика необходимы для работы приложения.
Какие существуют альтернативы MVVM и MVI в архитектуре приложения?
-Альтернативы MVVM и MVI включают в себя, например, Clean Architecture, которая разделяет приложение на несколько слоев, включая домен, представление и ввод-вывод.
Какие дополнительные ресурсы предлагает автор для изучения MVVM и MVI?
-Автор предлагает участие в бесплатной онлайн-работе, которая будет посвящена основным темам для Android-разработчиков, включая архитектурные шаблоны, такие как MVVM и MVI.
Outlines
📚 Введение в MVVM и MVI
В этом параграфе представитель разработки Android-приложений вступает в дискуссию о двух популярных архитектурных шаблонах: MVVM и MVI. Он заметает, что многие разработчики выбирают один из шаблонов без полного понимания их различий и преимуществ. Автор видео обещает провести сравнение MVVM (Model-View-ViewModel) и MVI (Model-View-Intent), чтобы зрители могли определить, какой из шаблонов подходит лучше для их проектов. Также упоминается ожидаемое большое объявление проекта, посвящённого основам разработки Android, и бесплатный онлайн-семинар, который будет проведен 27 апреля.
🔍 Общие черты MVVM и MVI
Автор объясняет, что оба шаблона являются представлением шаблонов и предназначены для разделения слоя представления в приложении. Он уточняет, что эти шаблоны не должны путаться с другими, такими как Clean Architecture, и что они относятся только к части приложения, отвечающей за представление данных. В этом параграфе также определяются термины 'модель' и 'представление', которые являются общими для обоих шаблонов, и рассматривается их роль в реализации бизнес-логики и структуры данных приложения.
🛠 Различия между MVVM и MVI
В этом разделе видео скрипта подчёркивается, что основное различие между MVVM и MVI заключается в подходе к обработке пользовательских действий и состояния UI. В MVVM используется ViewModel, который содержит логику состояния, в то время как в MVI - ViewModel обрабатывает 'намерения' пользователя, определяя, как должно изменяться состояние приложения в ответ на действия пользователя. Автор предоставляет примеры реализации обоих шаблонов на Android, демонстрируя, как они могут быть использованы в одном проекте, и объясняя ключевые различия в их структуре и использовании.
🤔 Выбор между MVVM и MVI
Автор завершает видео, обсуждая преимущества и недостатки обоих шаблонов. Он подчёркивает, что выбор между MVVM и MVI должен быть основан на личных предпочтениях и потребностях команды разработки. Автор не рекомендует 'религиозное' следование какому-либо шаблону, а скорее предлагает попробовать оба и выбрать то, что лучше всего подходит для конкретного проекта. Также упоминается, что важно обеспечить единообразие в использовании выбранного шаблона в команде для эффективного и последовательного разработки.
Mindmap
Keywords
💡MVVM
💡MVI
💡архитектурные шаблоны
💡ViewModel
💡Model
💡View
💡Intent
💡State
💡Reactivity
💡Jetpack Compose
Highlights
Introduction to comparing MVVM and MVI patterns in Android development.
The importance of understanding the difference between MVVM and MVI to avoid blindly following ideologies.
MVVM and MVI are both presentational patterns, not full app architectural solutions.
Explanation of the term 'model' in MVVM and MVI, focusing on business rules and logic.
Clarification that the 'view' in both patterns refers to the UI visible to the user.
The role of the view model in containing state mapping logic in both patterns.
Practical examples of implementing MVVM and MVI in Android development.
The structural differences between MVVM and MVI, particularly in state management and intent handling.
MVI's approach to bundling user intentions into a single state object and action interface.
Critique of MVI's additional layer of intent, arguing for a simpler approach in MVVM.
Advantages of MVI for readability and ease of understanding screen state changes.
Performance considerations when using MVI with a single state class in reactive programming.
The flexibility of combining states in MVVM despite having multiple state fields.
Addressing criticisms of MVVM and MVI and providing counterarguments for each.
Recommendation to try both patterns and choose based on team preference and project needs.
Emphasis on not becoming religious about architectural design patterns and maintaining flexibility.
Invitation to a free live online workshop on essential topics for Android developers.
Conclusion and call to action for feedback on preferred patterns and learning outcomes from the video.
Transcripts
hey guys and welcome back to a new video
when learning about Native Android
development you really don't get around
the terms mvvm and mvi some people swear
on using mvvm some other people say mvi
is the best pattern for every type of
app and I also have the feeling that
most people don't even understand what
the real difference is and then just
blindly follow some ideologies from
other developers so in this video I will
really compare these patterns once and
for all so you will know what is the
same about those what are crucial
differences and at the end you will be
able to choose the right pattern for
your project and all of that I will not
just say straight into this camera but I
will actually show you practical
examples so you can see right away what
those differences are just one thing
before as you've maybe seen in the last
video I am currently working on
something really big on something that
will teach you all those Essentials all
those fundamental practices every
Android developer out there has to know
if you're aiming to have a place in the
industry and on Saturday April 27th I
will host a free live online Workshop in
which I will share what all those
essential topics are for Android
developers so software engineering
Essentials like architecture code style
best practices but also those technical
Essentials so those technical topics you
have to know as a professional Android
developer and then at the end of this
Workshop I will reveal my big project
Essentials so if you want to be part of
this Workshop click the first link in
this video's description and save your
free spot but coming back to mvvm versus
mvi let's first of all talk about what
is actually the same about these pattern
in the end both mvvm which stands for
model view view model and mvi which
stands for model view intent both these
architectural design patterns are
so-called presentational patterns and
that's already the first thing most
people don't know those patterns are
only meant to separate your presentation
layer in different parts they are not
meant to separate your whole app into
different parts because I often hear
people talk about should I use mvvm or
clean architecture no those are very
different things you can use both in one
project because clean architecture
separates your whole app into different
parts into different layers while MVM
will only separate your presentation
layer which is really only one part of a
clean architecture project into
different parts so now that we know what
these two patterns stand for mvvm model
view view model and mvi model view
intent we can first of all think about
the common terms that are included in
both these patterns that is on the one
hand model and view let's first of all
understand what a model is because a
model is a very broad term in the sense
of software engineering and can refer to
a lot while in the case of mvvm and mvi
the model implements the business rules
and business logic so that means they
just Implement project-wide requirements
and if we think of an app like a social
network app where users have profiles
where they can post something where they
comment under posts then these are
project right requirements that hey we
want to have comments under post and
these are the data types that a comment
must have then these business rules will
also tell you what a post actually is
what does a post consist of is it just a
text Does it include an image and in the
end in cotland those are very often just
normal data classes as we can see here
we have a common data class and that
just encodes the logic or the rules that
make a comment model in the scope or in
the domain of this specific social
network project so we say Okay a comment
definitely has an ID it has an author
who wrote that comment which again is
another model a user model which I will
show you in a moment and it has some
content in form of a string if you then
take a look at the user model then you
might see okay a user also has an ID a
user has a username an email a specific
role maybe which could be user or admin
and then you can see such a business
rule could also just be a function here
part of such user class because whether
a user is allowed to dedi a specific
post that is very specific and that only
gets clear from reading the requirements
of the project so it's really specific
to the domain of your project since in
this case if you're an admin you can
delete any post and if you're user you
can only delete the post if your uh if
the ID of the user is actually the same
of the author so if the user is the
author of the post then they can delete
it and just for the sake of completeness
we Al have a post model each post also
has an author a Content an image URL a
list of comments and a Boolean whether
we like that post or not so that is
already one part that is the same about
mvvm and MBI now in Android we often
work with a separate domain layer and
the past one to two minutes I already
mentioned the term domain quite often so
in case you have such a domain layer the
model is not strictly part of the
presentation layer but rather of the
separate domain layer but you don't have
to work with such a domain layer and if
you don't then the model is part of the
presentation layer which is then part of
either mvvm or mvi in this case all
right so that's the model which is
common between these two patterns then
the so-called view is also common and
the view in the end just refers to
what's visible to the user so your
actual UI and on Android that would
either be your XML layout or the actual
view class or if you're using jetpack
compos it would be the composable so in
the end both these patterns just try to
separate your presentation layer into
distinct parts so what's visible to the
user where data comes from the model and
one more thing in which these patterns
now differ a little bit The View model
so while in mvvm the term view model is
contained in the abbreviation in MBI
it's not because it stands for model
view intent so there we have this intent
yet on Android both these patterns are
typically implemented with a view model
pattern so the job of the view model is
to contain the state mapping logic so
that means it processes incoming UI
actions like a button click like a
refresh swipe and then decides based on
these actions how the state needs to
look like after these so if we swipe to
refresh the view model has the job to
decide okay now I need to show the
loading indicator while we're actually
refreshing after that I have to show the
new items in the list so that way in the
end we really have a dumb UI on the one
hand which just takes in incoming State
and decides what that state now means
for the UI then we have the view model
which decides how the state needs to be
constructed and we have the model from
where our business logic our business
rules and all the data comes from so now
that I've sat that the model The View
and also the view model in most cases is
the same between those two patterns
what's really the difference and for
that on the one hand I have prepared an
example that shows you mvvm implemented
with a single screen and also an example
of mvi and that will really help us to
understand the differences taking a look
at our mvvm screen so here I have an MVM
screen root composable which just takes
in our nav controller and our view model
reference and then forwards the states
which are hosted from The View model to
the actual screen composable that is
just a common pattern I use that I have
such a root composable and then the
actual screen composable since if we
would pass a normal view model to a real
screen composable then that would break
the preview since our preview is not
able to construct view model references
that have a Constructor so this type of
structure with this root screen and this
normal screen composable uh this has
nothing to do with mvi or MVM it's just
something I would always do for compos
screens but if we now take a look here
at this screen you can see um this would
just be maybe a post details screen in
the domain of our social network app
here we get some post details which are
null because they need to be loaded we
have a Boolean whether we're currently
loading these we have a Boolean whether
the post is liked or so and then we also
propagate up these lambdas so when the
user does something on that screen and
in the UI we will then simply interpret
the state so what this really means for
the UI we check okay if it's loading
then we definitely want to show a
loading indicator and if not we want to
display some kind of pose details and in
our view model this will look like this
so we have an mvvm view model we have
all those different states that have an
impact on our UI they could be State
flow they could be comp poos state that
is really independent of this pattern
here and the view model then contains
the logic how and when the state should
change so here initially we load the
post maybe from our API or so when we
want to toggle the like we will just
change the post detail State here with
the like being toggled and when we want
to load a post we would first of all
update the loading State we load it from
maybe a repository a use case or so and
then again update is loading to fold
again so the view model decides how
these states change so this is how mvvm
is structured let let's now take a look
at mvi so this would be an example for
an mvi screen so you can see the first
part is already very similar we receive
a nav controller reference and a view
model but then the list of arguments for
the screen always looks a bit
differently so here we pass one single
state down to our screen composable and
we receive one so-called on action or
onevent Lambda and that is already the
core difference between mvvm and mvi
with mvi on the one hand we put all of
our screen State into one single state
rapper class into UI State class which
looks like this for example so in the
end we really just expose a single State
field to the UI including all those
single fields that could have an impact
on how the UI looks like and then we
just treat this state class as a single
source of Truth kind of for that state
which should only contain immutable
properties that can't be changed and if
our state changes then the goal with mvi
is to just replace the whole state with
a new instance and the changed Fields so
if we want to update is loading from
false to true we would create a new
instance of of the state class just that
we set is loading to true in that new
instance and leave all the the other
fields unchanged so that's one
difference about mvi the other
difference is this onaction Lambda and
this actually implements the intent part
about mvi so mvi model view intent the
intent part is different compared to MVM
it has nothing to do with intents of
Android so the Android concept but
rather that we want to bundle the
specific intention a user could have on
a certain screen so in the end every
single user interact that could happen
on a specific screen will be packaged
into such a action class like in this
case to toggle alike or to go back and
on cutland that's typically implemented
with a sealed interface where we can
then check in the view model which
intent or which action the user actually
sent from the UI to the view model and
if we then take a look in the view model
on the first glance it looks very
similar but the main differences are now
that we have an mvi view model we only
have a single State field which is
implemented by our UI State class I've
showed you previously so compared to
mvvm just to bring that up again here we
have every single field as an individual
State reference here in MBI we just have
a single state class and in order to
process these actions these intents that
are coming from the UI The View model
needs to expose such an onaction
function or on event function which then
takes the actual intent and checks in
when expression what should actually
happen for which specific type of action
for example when we tole the like it
would call the private function toggle
like which would again change the local
state in this case with state. copy
which just creates a new instance of the
state and allows us to change just one
field or multiple fields of that state
in this case the post details value so
those are already the differences and
you can see that the differences between
mvvm and mvi aren't actually too big
it's really just about this seal
interface and putting all states
together in one UI State class but the
rest is usually implemented in exactly
the same way on Android one thing we
need to be a bit careful with with MV is
if we have such actions that aren't
actually processed by The View model
like going back because that requires
the nav controller which we usually
don't have in the view model so in MV we
would actually need to go to our MV MV
screen route here and here in this
onaction Lambda where where we just
forward all actions to the view model by
default we would need to intercept these
actions and first of all check if the
action needs to be handled by the UI
itself so when that action is go back
then we want to use our nav controller
to maybe navigate up otherwise we ignore
that here in the UI layer but then we
still forward all actions to the view
model that is actually something we
would need to do here but only if such
actions need to be handled in the Y
directly but in a lot of cases you also
don't have that and you could simply
replace this with what I had before that
you just say VI model double colon on
action so what is now correct what
should you use for your Android apps
well I don't want to tell you use this
or use that in the end both these are
very viable and very popular patterns
but my goal and my intention here is
just that you understand the differences
you try them both out and then decide
for yourself what you enjoy more what
might fit better to your team because in
the end it doesn't help you if you stick
to a pattern but only a single part of
the team sticks to that and the other
the other part just introduces some
inconsistencies then there is no real
point of introducing a design pattern at
all but just to maybe highlight the
advantages and disadvantages of each
pattern so the critics of MV say that
having such an intent layer such an MV
action seal interface in this case is
just an unnecessary extra layer because
you could also just expose callbacks in
your screen and call The View models
functions directly which is pretty much
what mvvm does the critics often say
that if you have a large screen you will
have a very large when expression here
checking for the particular action and
to some degree that's true obviously
this action sealed interface is some
kind of an extra class an extra layer
but on the other hand it makes the
screen composable much lighter and much
easier to read in my opinion since for
every single screen in your app you only
need two parameters which keeps them
pretty light also about the critic
regarding the when expression I
personally never really understood those
people why uh potentially big when
expression is an issue because you can
still work with single private functions
and it's very easy to spot what happens
in which specific scenario and if you
wouldn't have this single function and
all those other functions would be
public for a very big screen then what
would happen for your compose UI is that
the list of parameters here would grow
by quite a lot because every single
function from The View model would need
to be a separate Lambda every single
state would be would need to be a
separate uh field here and of course you
can argue you can um combine multiple
related States into a data class maybe
you can argue that you could potentially
also combine such multiple callbacks
into a data class but then you again
have that extra code which these critics
complain about for mvi so does it really
make a difference in that case another
common criticism of MV is that if we use
mvvm and we have all those States as
separate Fields it's much easier to
combine them let's say they were state
flows and we want to combine multiple of
these State flows then that would be
much easier with single States than if
we would have one single state class so
one common example might be that you
have maybe some some kind of email field
here or so we have a private Val email
which is a mutable State
flow empty string by default and we have
aoan is email valid which you could now
Implement with reactivity since every
time our email changes we want to map
that for example to I don't know some
kind of valid dator is valid email with
the changed email and we then call State
in
and convert that to some kind of state
flow with a typical way here while
subscribed and an initial value of false
so the critics of VI often say that if
you have such single Fields you can
implement this reactivity much better
you can better combine different states
but that's also not really true because
if we just have one single um one single
compost State here in our MV view model
then we can also easily convert that to
State flow so we have a function for
that where we can let's say um we also
have these fields here so Val email
empty string by default and we have an
is email valid Boolean which should
update in real time when we change the
email actually Boolean and we then in
the view model and we want to react to
changes of our email field then we can
do that with a snapshot flow so we could
just go in here we could have a snapshot
flow which will trigger whenever the
compos stes in here actually change so
whenever our email changes we can also
map that flow now to our validator that
is valid email with the changed email
and then state that in or just update
our actual State here with State state.
copy is valid email is equal to the new
value and we launch that in view model
scope that would be the equivalent code
here with mvi so just to show you you
can also react to changes of specific
singal Fields when using such a single
state class and all in all my own
opinion is that mvi is just a bit more
readable because we can just take a look
at the state class and in just five
lines of code we can completely
understand all of those values that
could change on a single screen while
with mvvm we will very often have a long
list of States here first of all if
we're using State flow then we will
actually have two Fields per single
state flow because we always have one a
public State flow and then one immutable
one where we would have an email is
equal to email as state flow and if our
screen state contains 30 States then you
will have 30 such pieces of code while
with MV you can understand that at
almost a single glance for a big screen
one thing you have to be in fact a bit
careful about mvi is that if you have a
single state class and you're using X L
and then collect that single state in
just a normal flow collector then that
will trigger for every single change of
your state so the whole flow collector
will trigger even if you just update the
single is loading Boolean which is a
performance disadvantage compared to
mvvm where you can have multiple such
flow collectors for every single field
on the other hand for Jetpack compost
projects it's not such a big deal
anymore because compost is smart enough
to detect which Fields actually changed
when there is a new instance of MBI
State being passed sometimes it does has
its issues especially if you use
unstable Fields here in such a state
class like a normal list where compost
can tell for sure if that not changed or
not but those are really just a few
situations and in this case I'm a friend
of not dealing with this premature
optimization so not trying to optimize
the performance before it becomes even
an issue and on the other hand
preferring the better readability in
your code so that's why I overall tend
to stick to MV in my projects but that
doesn't mean MVM is bad that doesn't
mean MV is the best one don't become
religious about such AR architectural
design patterns try them out see what's
good for you and then use that and you
will have a good project structure with
either of these patterns so let me know
down below what kind of pattern you
actually stick to and if you learned
something here that you didn't know
before and other than that thanks so
much for watching this video again Link
in this video description regarding the
live Workshop in one and a half weeks
and other than that have an amazing rest
of your week see you back in the next
video bye-bye
5.0 / 5 (0 votes)