Which Software Architecture Should You Use: MVC, MVP, or MVVM?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today I'm going to talk about GUI architectures one you might have heard of is MVC or model view controller but there are others as well such as model view presenter MVP or model view view model mpvm so what's the difference and which one should you use do you even have a choice unfortunately there's no clear consensus of what these architectures actually are I've looked up a bunch of different articles over the last week trying to find the right correct definition of each but I found a lot of contradictions and people going to war over the details so I've tried to distill the main differences between these architectures into three examples of the same relatively simple GUI application but each time I've set it up slightly differently I'll then highlight what I think is the main distinctive feature of the particular architecture it may not always be completely correct because I'm also dependent on how the different GUI Frameworks operate I'm going to use TK enter to show the difference between MVC and MVP and I'll use my iqt with a UI definition file to illustrate mvvm when you start creating a new application choosing the right architecture is important but there are lots of other things to consider as well I've written a free guide to help you get set up quickly you can get it at Ironwood codes design guide it contains the seven steps I take when I design new software and hopefully it helps you avoid some of the mistakes I made in the past iron dot gold slash design guide and Link is also in the description of this video today we're going to work with a really simple to-do list example it's built on TK enter it's one single file I'll show you another version later that uses one of the architectures that we're going to talk about let me start by running this application so this is what you get so we have a list of to do items here I can add a new task like so press enter and it's going to be added to the list and I can click on one of these tasks and delete that like so how does this work well there is simply a fixed constant value task list here that the application is initialized with later on I'll show you a version of the same application that persists the tasks to a database which is actually really simple to set up then we have some texts that are going to be used in the application and then we have a single large class to-do list let me close the terminal and this is a pretty simple class it also contains a lot and that's one of the issues that I'm going to talk about today so it sets the title sets the size it inserts the tasks from the task list variable that we get here as a parameter then it creates user interface so there are some things in the frame there's a couple of buttons a text field to enter a new task and then we have a couple of methods like handling adding tasks deleting tasks things to do with selecting or deselecting tasks that this actually disables and enables the delete button so that's pretty basic behavior of a to-do list application now we have a main function that creates an instance of the class passes the constant that we saw at the top of the file and then starts the main Loop and that's all it does now this class obviously tries to do too many things in particular it handles both GUI aspects and data model aspects and this is exactly where architectures like MVC or MVP or mvpm play a role MVC stands for model view controller it was created by trigly greenscock which I completely screw up the pronunciation of while working on Small Talk 79 in his design a model represents the knowledge in the system a view is a visual representation of the model retrieving data from the model to display to the user and passing requests back and forth between the user and the model a controller is an organizational part of the user interface that lays out and coordinates multiple views on the screen and that receives user input and sends the appropriate messages to the underlying views Small Talk 80 supports an evolved version of MVC here view represents some way of displaying information to the user and a controller represents some way for the user to interact with the view a view is also coupled to a model object but the structure of that object is left up to the application programmer showing different GUI architectures in python or any programmed languages actually pretty hard because we're also dependent on what the GUI Library supports now I've tried to create an example of showing both MVC and MVP with TK enter because I think we're able to do that with TK enter but for the mvvm version of the architecture I'm going to use yqt so what we have here is a simple setup of model view controller and the way that I've set this up is that the view is the graphical representation so that's the file that you see here so this is basically for a big part of class that we had in the simple version I showed you before that's a to-do list class then we have a model and that model represents the data so in particular what you see that's doing here is that it provides a connection with sqlite so in the initializer it creates a connection with the database and then it checks if there is a table for containing the tasks if not it creates one and then we have methods for adding a task deleting a task and getting the tasks that are currently in the system so that's the model that's the interface with the database and then the controller is viewed as the system that passes the messages between the GUI and the model so the control then obviously needs a model and a view so that's what it's getting here and it's storing that as instance variables and then it sets up The Binding so if you look at the view class you see that we have well next to this create UI method that we already had before so you see that we now have two new methods Point delete and bind add and those are going to provide the connection the communication between the GUI and the model ultimately and then that communication is dealt with by the controller so for example in order to add a task the controller gets the text from the text field it then clears it it then adds a task to database using the model interface and then it tells the view to update the list of tasks because of course a task has been added and delete is very similar in that the model has a delete task so from The View we're going to get the selected task and that's actually a property where is it yeah it's down here so this returns a string containing the selected task and then the controller instructs the model to delete that task and then it tells the view to update the task list and then finally the controller also has a run method that starts the main Loop in the view if you look at the main file that's basically how it's set up we create a model we create a view which is the do less class and then we have the controller that is going to need both of them because it handles the communication and then we call controller dot run so the controller really controls everything in the model view controller architecture if you run this you get practically the same result as before so I can now type some tasks I'm going to add a video script I'm going to write a a blog post go to the supermarkets I can basically add these tasks here and then if I close the app and I start it up again you see that we get the same number of tasks because now it's persisted to the database that's what the model is doing then I can also delete tasks again by the way there is a bug in this specific implementation namely the delete us simply deletes all the tasks that have a particular title so if you have tasks with the same title it's going to delete both of them and that's of course not what you want in a to-do list the reason I kept it in here is to I wanted to keep the database really simple normally you would probably add some sort of ID to each task and then you can delete it by ID and then the problem is solved so that's model view control the model is completely independent it's simply a layer on top of the database that allows us to perform operations on the data the controller has both the model and the view and coordinates them so if something happens in the view the control updates the model and then tells the view to update itself and the view doesn't have any knowledge either of the controller but it does have the model so if you look at for example the update task list methods so what this does is that it gets the latest tasks from a model and then and displays it on the screen by the way if you're enjoying the video so far click on the like button that's going to let YouTube update the model so that it's going to control what the viewer is going to view are we getting tired of these puns yet I am getting a bit tired of them anyway just click the like button it's really going to help me thanks the fact that the few has knowledge of the model is one of the criticisms of model view controller in that there's lots of connections between these three different things the model is sort of independent but the controller is coupled to both the view and the model and the view is coupled to the model so you get this kind of triangle of things that are dependent on each other and that's not really great an evolution of model fuel controller is model fuel presenter and that tries to solve this issue and that slightly changes the role of the controller in model view presenter that's called not a controller but a presenter and it serves more as a layer between the view and the model and handles the communication and that's nice because that means if you change things in a model then only the presenter needs to be updated and the view you don't have to touch a second thing that you do in model View Press enter is that you introduce some abstraction in this case controller is dependent directly on this very specific View and the view again dependent on a very specific model and we want to separate those things a bit more so they're a bit easier to change they're a bit more decouples so how do we set this up well first we have the controller and we're going to rename this to presenter like so and then I'm also going to change the class name of course this doesn't do anything it's really for clarity so there we go now in principle we're not going to change a lot of things here but mainly we want to remove the direct dependency on the to-do list view so what I'm going to do instead is I'm going to introduce a class and I'm going to call that view and I will use a python protocol for that and for some reason that doesn't want to import automatically so we'll just do the old-fashioned way so we have View and the view is going to have a couple of methods that we're going to use here now binding is something I'm also going to do differently so I'll I'll leave these two here for the moment but we are going to need things like get entry text and clear entry so let me add those methods now so we have clear entry that's clears the text field and we have get entry text and that's going to return a string value which is the current value of the text field now before I change more things here I want to update the view a bit so on the side of the view one of the issues is that the view was directly dependent on the model so I want to change that so one thing I'm going to do is simply remove this here like so and we're not going to store the model internally anymore and when you look at the view let me scroll down a bit you see that actually the only place where the model is actually used is an update task list what we can do instead is not let the view get the tasks from the model but simply pass this value here as an argument so I'm going to add here a list of strings which is going to be the updated list of tasks and then instead of getting it from the model we can simply iterate over the task that we get as an argument another thing that I'm going to do differently is these bindings so here we have methods to bind the delete and add tasks but actually what's common in model viewpresenter is that the view has some sort of reference to the presenter and the way we can do that is we have our create UI methods that we pass here a presenter and then since we have the presenter here we can now perform The Binding directly here and then let's also introduce abstraction in the view so we have a class presenter which is again a protocol which apparently I'm still not able to import automatically and then this is going to have a handle at task and that needs an event and that's going to return nothing and we have a handle delete task like so and now what we can do since we have a presenter here we're not importing anything I'm simply using the protocol actually model we're going to remove because that's dependency is now gone and then here we pass the presenter and then we perform The Binding directly here so we have two bindings we have to delete task so that's this one and we can do that here so we're going to bind it with presenter dot handle delete task and then this method we don't need it anymore and adding tasks very similar we have the my entry and here we're binding that with presenter dot handle add task and then we also don't need this method anymore so that's way cleaner in my opinion and now I think we simply have to update the presenter bit because this should be handle our task and handle delete task there we go the bindings we don't do them here anymore which really simplifies the presenter a lot and then let's change this to use the abstract view the view protocol class and of course there are some things missing like we don't have update task list but we have updates task list that expects a list of the current tasks because that's what we added here so let me add this method here update a task list and that's going to expect a list of strings and come to return no and what we can do is let's create a helper function here update task list and we're going to get the list of tasks like so and then self.u.update task list and we're going to pass the tasks there we go and now here whenever we add a task or delete a task we simply call that helper method to make sure that the task list is up to date like so the run method needs to do a couple of different things few dot create UI I think I called it create UI where is it yeah create UI so that one we also need to add here create UI itself and that's going to need a presenter like so and we need from future the annotations otherwise this doesn't work to-do list we can delete because that's no longer used and then in run we do self.view dot create UI and we pass the presenter which is this object which is self then before we can actually start we need to do self dot update the task list there we go and then we can start the main Loop and we also need to add the main loop as a method main Loop there we go so now the presenter really served as an intermediary between the view and the model so that's quite different from model view controllers model view presenter and there's abstraction the presenter doesn't import the view it simply has a protocol class and a few also doesn't import the presenter class it also has a protocol class and since we set up The Binding here we can keep this relatively simple and we have a couple of helper methods to change and update the view we just need to change a few things in the main file now of course we don't have a controller anymore but we have a presenter there we go we still create the model obviously we also create a view but that no longer needs the model and then we create the presenter and just like before the presenter gets the model and the view so now both the model and the few they are kind of separated from the rest of the code let me run this just to test that this actually works and it doesn't why doesn't this work in presenter we have to create the UI and apparently this is missing something so we're passing self so that should be okay if I go to the view we have create UI we have self and the presenter so why is this not working oh actually we don't have to do this anymore that's the difference because that's being done from the presenter let's try this one more time yeah this looks better we have go to the supermarket let me add something else say hi to my YouTube audience and I'm not gonna go to the supermarkets because I just can't be bothered so I'll delete that one again so much better decoupled model is still independent we actually didn't need to change anything in the model but presenter has a view protocol class and few has a presenter protocol class so there's some abstraction in there now I use protocols here you can also use ABCs if you want to they have a bit of a different kind of application I did a video a while ago where I talk about the difference between protocols and ABC classes and when to use which one I've put a link to that video at the Top If you want to watch it mvvm is yet another way of approaching things model refers either to a domain model which represents real estate content that's like an object-oriented approach or it refers to the data access layer and that represents content so that's more data Centric approach just like in the model view controller and model view presenter patterns the view is sort of the structured appearance of what the user sees on the screen and then it displays a certain representation of the model and retrieves the user interaction with the view that can be Mouse clicks or keyword Imports or anything and then it forwards the handling of those to the view model via data binding so data binding that's the core difference what separates model view view model from MVP and MVC The View model is then an abstraction of the view that exposes properties and commands and then instead of the controller of the MVC pattern or the presenter of the MVP pattern mvvm as a binder which automates Communications between the views and the bounds properties in the view models the main difference between viewmall and presenter in MVP pattern is that the presenter has a reference to a view whereas The View model doesn't have that instead a view directly binds to properties on The View model to send and receive updates so that requires a binding technology or something that generates some boilerplate code to The Binding a nice example of GUI library that supports this Pi qt in piquity we have dot UI file that represents the structure and layout of the view which is Created from the file web framework we then have a view model class that contains the properties and objects if we change any of these the view is updated automatically I just want to quickly show you an example of what model view view model can look like when you do it in Python so this is again the same application a to-do list I kept this one pretty simple I didn't add the database functionality here but I think you get the point of how it's set up so in this case we have a few steps we have an app that creates the QT widget application then we create the view model and view model we show and then we run the application that's how it's set up in yqt so we have a view which is in principle a representation of the view in this case using a DOT UI file so this uses XML I hate XML but well this is how it works and here we basically specify the whole layout of the view and what things are called and whether they are enabled for example here you see where I have the delete task button so that works in exactly the same way and then we have the model that is again based on the simple example I had in the beginning where we simply have a constant containing a couple of tasks and that creates a model and simply fills it and I'm using here the QT model so I can easily couple it with the view and then the view model is actually a class that provides the binding so this loads the UI from the UI file that I Define here and then it has binding it already has the difference the task lists and things like that now this doesn't really work that well with the typing because obviously we didn't specify these things because they're generated from the UI file but this handles basically the connection between what's in the UI file and what's in the actual view model and then if you update the view model it also updates the view now strictly speaking is not entirely correct the way I set up because probably what this load UI thing does it is simply generates the UI and it not so much provides a binding but I think it's close enough to at least show you how it's supposed to work and then what you also see here is that the view model then communicates with the model so if we add a task here that's on our task then we're going to task list model and there we can append a row and when we deleted us we're going to remove a row from the task list model this is a bit of a contrived example because we don't really have mvvm in Python but what I hope it shows is that the main difference between architectures like MVP and MVC and mvvm is that mvvm has data binding to the mix so there is this view which is the representation of the graphical user interface and we have the view model which binds data so when you update some of that data in the view model it's going to update a few automatically that's how it works so what about Django's architecture well according to the Django website they call their architecture an MTV architecture model template view quote from the website site in Django view describes which data is presented but if you normally delegate to a template which describes how the data is presented the controller is then the framework itself the Machinery that sends a request to the appropriate view according to the Django URL configuration the way that Django sets up their architecture is kind of related to how Martin Fowler defined the MVC architecture in 2003 where an input controller receives a request sends the appropriate messages to a model object takes the response from that model object and then passes it to the appropriate field for display in the end we can debate all day about the intricacies of what a view controller model template presenter is the goal in the end is to get the job done in a logical way I hope you enjoyed this video that it gave you an idea of what each of these architectures mean MVP or something close is my preferred starting point however the exact architecture you should use in a particular situation it's not written in stone the most important thing to remember is to separate things in a GUI application and not put everything into a single huge God class where you put those lines of Separation depends on the good platform you use opinionated it is and which flavor of architecture you personally prefer next to what I've shown you today there are other ways to separate things more to better decouple your code if you want to learn more here's a video where I take you through five things you should do to reduce coupling thanks for watching take care and see you soon
Info
Channel: ArjanCodes
Views: 74,353
Rating: undefined out of 5
Keywords: software architecture, gui architecture, model-view-controller mvc pattern, model-view-controller mvc, model view presenter example, model-view-controller, model-view-presenter pattern, model-view-presenter mvp, model view presenter, model–view–viewmodel, mvc vs mvp vs mvvm, pyqt, pyqt tutorial, model-template-view (mtv) architectural pattern, model–view–viewmodel (mvvm), model view presenter vs model view controller, model-view-controller software design pattern
Id: eHhXoCNCI1c
Channel Id: undefined
Length: 24min 26sec (1466 seconds)
Published: Fri Dec 30 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.