Help me understanding the MVC model

Started by
8 comments, last by Glass_Knife 11 years, 1 month ago

I've been trying to understand this model for a time now, but I don't really get it. I've seen that picture everywhere with model - control - view and yadda yadda. I understand the concept, but I don't get the thing with observers and stuff. I've tried to look at simple examples, but they are not simple enough for me I feel.

Can someone make an EXTREMELY short example of this in just a couple of rows? I don't want to have any details to make it perfect and those kind of stuff. Maybe you can just give me an example of how to change a String name = "xxx" and to change it to "yyy" with the control class file.

I want it as easy as possible and ignore every detail that makes it better and that kind of stuff. Just a basic understanding would be super! (a working code of course).

I would be very happy if someone could help me with this!

Thanks in advance!

Advertisement

Generally ignore the concept of observers.

The general gist is you have...

A model: which is a representation of the data

A Controller: Tasked with manipulating the data and applying logic to the data

A View: Tasked with displaying the data.

So you may have a model called ProductList. It stores a bunch of products.

The controller would contain methods to say add a product or remove a product and a method render the appropriate view

The view would display the data and possibly allow interaction with the controller.

Essentially you are creating a chain of command. You see the data with the view and you use the view to tell the controller what you want. The controller is the middle man between the view and the model to ensure everything done to the model is done properly. The goal is to create a layer of separation between your data, data logic, and visual data representation.

Bringing Observers into it just complicates the understanding and I feel it is not really necessary.

That was a quick answer! Thank you!

Could you maybe give a very simple code example of your idea about the ProductList? :)

Generally it may look something like this crappy psudo code

Class ProductList

Products[]

Product GetProduct(ProductID)

Class ProductListController

prodlst ProductList()

AddProduct(Product)

RemoveProduct(Product)

// some other methods

RenderView(Filters)

// various view classes based off of filters to modify and customize the output

Wish I could give something more robust but I tend not to use MVC as I feel it is an over abstraction for most problem scopes that will get you into trouble. The most use I have seen for MVC is in web software.

A model: which is a representation of the data

A Controller: Tasked with manipulating the data and applying logic to the data

Although this is a common interpretation, this is not the original meaning of the model and the controller. The original meaning would be more like this:

  • Model: a representation of the data and the logic to manipulate it
  • Controller: translates input requests from the user into calls to manipulate the model

In other words, the Model handles all the important parts, the View is the output, and the Controller is the input.

The danger of having a controller "tasked with manipulating the data and applying logic to the data" is that responsibility for the correct use of the data is now split across 2 separate groups of objects, controllers and models. You have model objects that are barely more than just clumps of data and you have controller objects with implementations heavily coupled to those clumps of data. Why not just concentrate that information in the model, which then can provide a minimal interface for the controller to use when the user sends some input?

Maybe it'll help to explain it differently:

A Model is a collection of data and the structure of that data. A couple of examples: say you have a list of names in a text file. The names is the data, the fact that each name is on its own line in the text file is the structure. The more obvious example is a database: the entries are the data and how the tables are set up and connected is the structure.

A View is the UI and how the data is presented to the used. This is the buttons and rows and other visual elements that show up on the screen, along with the code to pass input on to the controller. Think dumb terminal; the View doesn't know what the data is, it only knows that it's going to display 10 rows of something it recieves from the controller and if the user hits the next button, it should tell the controller about that.

A Controller is what parses the data from the Model and prepares it for the View. It's the middleman between the View and the Model. The Model doesn't care how it's data is presented or even if all the data is used, it's fairly passive. The View doesn't care what the data is, only what fonts or screen regions are going to be necessary to show it. The Controller is what takes the View's input, finds the appropriate data in the Model, and gives it back to the View. The Controller is like a waiter; you (the View) point to an item on the menu, and the waiter gets that item from the kitchen (the Model). You don't care how it was made in the kitchen or what sort of maze the waiter went through to get the dish; you only care that the correct item was given to you.

The Controller is seperated from the Model because you should be able to change the data without affecting how you retrieve/filter it. The View is seperate from the Controller because retrieving/filtering data has no affect on HOW it is presented, only WHAT is presented.

To use a more concrete example:

pokedex.png

This is a screenshot from PokeIndex 5th Gen, an app I made for iPhone. The Model in this case is a literal database with the Pokemon's number, name, and filename of the image. The View is a table view: it doesn't know or care what Oshawott is, only that it has to display a 32x32 image, format a 3 digit number with the Marker Felt font at 20 point size, and do the same for a text string. It also has to be pass to the controller a message if any of the rows are tapped. The Controller handles loading the Pokemon info from the database, filtering it (by Pokemon number in this case), and preparing the info in a way the View can use.

I could change the Model to use Pokemon X and Y instead of Black and White and that won't affect the Controller. I can change the View to display a grid of Pokemon instead of a list and that won't affect the Controller. This is the encapsulation that the MVC pattern is designed for. But unless you have a certain degree of complexity in your Model (in this case, it's 650 Pokemon with all thier stats and locations), then the MVC pattern is over abstracting, as blewisjr said. If your View has constraints that keep it from changing, MVC may not be the best solution either.

That said, the iOS libraries push the MVC pattern pretty hard, so that would be one way of immersing yourself in it.

I want to add a comment about the observer pattern. But first I have to agree that it may be best if you do not need it. There is a kind of hierarchy in the MVC. The Model knows only about itself. That is, the source code of the Model includes no header files from either the View or Controller.

The View however, knows about the model. It includes header files from the Model, and polls the Model about the state every frame. That way, the View can draw something that is based on what the Model has done. But the View knows nothing about the Controller.

The Controller knows both about the Model and the View. If you click on the "fire" button on the mouse, the Controller knows what Fire function in the Model to call. If you press the button for switching between first and third person, the controller knows what function in the View to call to request the change.

The reason to keep it this way is to minimize dependency. No matter how you modify the View class, the Model will still work. Even if you move the Model from a Windows to an Android app, the Model can be moved with no changes. But the View probably need to be updated.

Now, suppose there are intermittent events generated by the Model. Things that happen unfrequently. Also suppose that the View need to react and show something (play a sound when a monster dies, etc). The wrong way to do this would be for the Model to call a function in the View when it happens. If you do that, the Model would need to include header files from the View, and there would be a double dependency. A better way would be for the View to do what it already does, poll for all such possible things, and play the sound when a flag (or something is set) in the Model.

This is where the Observer sometimes can be used instead. Depending on the requirements, it may turn out to be very inefficient to poll for all possible events every FPS. Instead, a callback can be used (there are other ways to implement the Observer pattern). The View registers a callback in the Model. The model saves this pointer, and only calls it when the event happens. The model knows nothing about where the callback goes, and so need not depend on the View.

[size=2]Current project: Ephenation.
[size=2]Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

A Controller is what parses the data from the Model and prepares it for the View. It's the middleman between the View and the Model.

The Controller knows both about the Model and the View. If you click on the "fire" button on the mouse, the Controller knows what Fire function in the Model to call. If you press the button for switching between first and third person, the controller knows what function in the View to call to request the change.

Without wanting to labour the point too much, these are both reasonable architectures to use, but they aren't what the original MVC was designed for.

Originally, the View would access information from the Model directly. For example, the model has a FullName() accessor, which the view calls to get the full name, and the view calls that function to get the string of data that it needs. So you might ask, how does the view know when to call the accessor? Usually the view is an observer, waiting for an update notification. Or the controller might be able to provide notification of an update directly. But the controller shouldn't - in the traditional system - be providing the data directly. That would increase the coupling between the parts of the system and make them harder to change. The Controller shouldn't need to know what information the View needs: eg. some views might only care about the LastName, some might care about the FirstName - if a controller asks to change the FirstName, what name information should it pass to the View? What if that View only cares about the LastName? The best answer is to let the View know that something has changed, and let it figure out for itself what information to query.

On the second example, if you actively change the whole View, that's something a bit out of the scope of the original MVC. Arguably this is when you need a "Presentation Model", which is sort of a Model for the View itself! This is one of the shortcomings of the original MVC system as it can't really handle this sort of change. This is probably why a lot of systems now have variations on MVC, like MVVM or MVP, because the original idea of MVC is both misunderstood and not always suitable for modern apps.

Good reading, although possibly a bit dense:

http://martinfowler.com/eaaDev/uiArchs.html#ModelViewController

http://martinfowler.com/eaaDev/PresentationModel.html

Thanks a lot for the information in this thread. Though I still don't really get it because I need some kind of code example I think. One proper example that will work which I could fiddle around with and play and try and understand :)

Without wanting to labour the point too much, these are both reasonable architectures to use, but they aren't what the original MVC was designed for.

Yes, I agree with this. I think it is important to point out that patterns are a way to study complex systems. Many programs have been written re-writing the same structure, so some really smart guys (the gang of four) cataloged and named them so there would be a common language when discussing them. Now I can say I used a Factory Method, and other programmers will know what I mean (hopefully).

More important than how you make a MVC is why. You can structure the code in many ways, you can remove one of the three MVC objects, and you can allow or prohibit the objects from knowing about each other, and each configuration probably has some different name. But the reason you structure your code this way is so that it is easy to evolve the system with the minimum amount of change.

By having a data object that knows about the data, and observers that can listen for changes to the data, you allow new observer to the data to be added later without updating the data object. This way your objects are loosely coupled. This is great for a GUI that waits for user input. Some data objects may be observed by dozens of different views when the program gets really large.

The view displays the data. If you are doing a game, then there will be an input module polled or sampled every frame for the data. But a GUI application doesn't work that way. Each view is the object that receives the user input. In this situation, the view needs a reference to the controller to pass on the user commands.

The controller knows what to do when the user input is received. Sometimes it will do things with the data, and sometimes it needs to affect the view, such as enabling or disabling controls. So to just decree that the view doesn't know about the controller, or that the controller only operates on the data and not the view, isn't practical when you start trying to make a program that actually does stuff.

Think of these patterns like the "Pirate Code". They are guidelines, not rules. Use them as an example of structuring you code so that you code is loosely coupled enough to be extendable without adding too much complexity.

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

This topic is closed to new replies.

Advertisement