MVVM vs. MVI - Understand the Difference Once and for All

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
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
Info
Channel: Philipp Lackner
Views: 17,030
Rating: undefined out of 5
Keywords:
Id: b2z1jvD4VMQ
Channel Id: undefined
Length: 18min 40sec (1120 seconds)
Published: Wed Apr 17 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.