May 5, 2008
Like everything else in software engineering, it seems, the concept of Model-View-Controller was originally invented by Smalltalk programmers.
More specifically, it was invented by one Smalltalk programmer, Trygve Reenskaug. Trygve maintains a page that explains the history of MVC in his own words. He arrives at these definitions in a paper he published on December 10th, 1979:
Models represent knowledge. A model could be a single object (rather uninteresting), or it could be some structure of objects.
There should be a one-to-one correspondence between the model and its parts on the one hand, and the represented world as perceived by the owner of the model on the other hand.
A view is a (visual) representation of its model. It would ordinarily highlight certain attributes of the model and suppress others. It is thus acting as a presentation filter.
A view is attached to its model (or model part) and gets the data necessary for the presentation from the model by asking questions. It may also update the model by sending appropriate messages. All these questions and messages have to be in the terminology of the model, the view will therefore have to know the semantics of the attributes of the model it represents.
A controller is the link between a user and the system. It provides the user with input by arranging for relevant views to present themselves in appropriate places on the screen. It provides means for user output by presenting the user with menus or other means of giving commands and data. The controller receives such user output, translates it into the appropriate messages and pass these messages on to one or more of the views.
It may seem like we're deep in Architecture Astronaut territory now, but bear with me. The MVC concepts are a little abstract, it's true, but it's an incredibly common pattern. It is literally all around you. In fact, let me bring it back down to Earth this way: you're looking at MVC right now.
|Model = HTML
||View = CSS
||Controller = Browser
This ubiquitous trifecta represents MVC almost perfectly.
The HTML is the "skeleton" of bedrock content. Text that communicates information to the reader.
The CSS adds visual style to the content. It is the "skin" that we use to flesh out our skeleton and give it a particular look. We can swap in different skins via CSS without altering the original content in any way. They are relatively, but not completely, independent.
So if you believe the web has been at all successful -- most signs I've seen point to yes -- then you also have to acknowledge the incredible power of Model-View-Controller.
It's no coincidence that many of the most popular web programming frameworks also encapsulate MVC principles: Django, Ruby on Rails, CakePHP, Struts, and so forth. It's also officially creeping into ASP.NET under the fledgling ASP.NET MVC project.
Just take a gander at the project layout in a sample ASP.NET MVC project:
It's almost self-explanatory, if you've ever built an application of any kind:
The classes which are used to store and manipulate state, typically in a database of some kind.
The user interface bits (in this case, HTML) necessary to render the model to the user.
The brains of the application. The controller decides what the user's input was, how the model needs to change as a result of that input, and which resulting view should be used.
It's beautiful in its simplicity, as Terence Parr notes:
For the "MVC" of a web app, I make a direct analogy with the Smalltalk notion of MVC. The model is any of the logic or the database or any of the data itself. The view is simply how you lay the data out, how it is displayed. If you want a subset of some data, for example, my opinion is that is a responsibility of the model. The model knows how to make a subset. You should not be asking your graphics designer to filter a list according to age or some other criteria.
The controller in a web app is a bit more complicated, because it has two parts. The first part is the web server (such as a servlet container) that maps incoming HTTP URL requests to a particular handler for that request. The second part is those handlers themselves, which are in fact often called "controllers." So the C in a web app MVC includes both the web server "overlord" that routes requests to handlers and the logic of those handlers themselves, which pull the data from the database and push it into the template. This controller also receives HTTP POST requests and processes these, sometimes updating the database.
I look at a website as nothing but a graph with edges with POSTs and GETs that routes pages.
Here's one quick way to test if your application has properly segregated itself between the Model, View, and Controller roles: is your app skinnable?
My experience is that designers don't understand loops or any kind of state. They do understand templates with holes in them. Everybody understands mail merge. And if you say, "Apply the bold template to this hole," they kind of get that, too. So separating model and view addresses this very important practical problem of how to have designers work with coders.
The other problem is there is no way to do multiple site skins properly if you don't have proper separation of concerns. If you are doing code generation or sites with different skins on them, there is no way to properly make a new skin by simply copying and pasting the old skin and changing it. If you have the view and the logic together, when you make a copy of the view you copy the logic as well. That breaks one of our primary rules as developers: have only one place to change anything.
Skinnability cuts to the very heart of the MVC pattern. If your app isn't "skinnable", that means you've probably gotten your model's chocolate in your view's peanut butter, quite by accident. You should refactor your code so that only the controller is responsible for poking the model data through the relatively static templates represented by the view.
The power and simplicity of properly implemented MVC is undeniable. But the first step to harnessing MVC is to understand why it works, both on the web, and also within your own applications.
Posted by Jeff Atwood
CSS is _definitely_ the View
Well, if you make HTML the model, then CSS is also part of that model, IMO.
CSS does not do anything to HTML in and of itself. That job is done by the rendering engine. CSS is extra information that it uses. So if you're using MVC to write the rendering engine, *both* the HTML and the CSS are in the Model. If either changes then the View (eg the display in the browser) has to change.
I find it useful and illuminating to think of the interaction of
HTML/CSS/Browser as an example of MVC
I find it confuses the issue, because it's not an example of MVC :-) I think there are far clearer examples. There would not be this disagreement if it was a good example.
Hey Jeff -
Does this mean that now that you're independent again, that you'll be returning home to your VB roots and be switching back to VB.NET?
Or have you fallen head-over-heels for C#? :-|
Inquiring minds want to know! :-))
I heavily discussed this with my class mates today. We all think the 'HTML/CSS/Browser' example is highly inappropriate in the case of a proper MVC model.
It's not wrong, it's just a bad example.
MVC is not just easy to understand but also is OBVIOUS and almost every program will meet with it.
All program have some part that "do things", other part that "show things" and other that you can "operate things", MVC just ask for separate those part on a "not-so" isolated space.
Anyways, a skinned application usually are MVC "complian" and a skinned-less application still can be a MVC one.
Well, if you make HTML the model, then CSS is also part of that model, IMO.
But HTML models a Document. CSS doesn't model anything, it only describes how the HTML is presented. A "presentation filter" as Trygve put it. Changing the CSS doesn't add content to the document. It is used to "highlight certain attributes of the [Document] and suppress others"
To take a more common example, let's say you decide to model an Invoice using a collection of BillingItems, then you want to present that to the user using a data-bound table (e.g. DataGridView).
That table has a LOT of extra information (Properties) that controls which columns to display and how to format them, what font to use, colours, border styles, padding, margins etc etc - but all that information is still part of the View, not the Model.
As per your argument, if either (the contents of the Invoice model or the properties of the table) changes then the display must change. But again that doesn't mean the table properties are part of the Model.
Interesting, just been learning about MVC Architecture in the context of EJB's. From what ive learnt the pro's of using this software abstraction of buisness and application rules far outway the negatives. Sounds like this is the way to go.
I think the examples in the article are very flawed. html css etc are bad examples, because they run everything together.
HTML and CSS include elements of all parts: model, view AND controller. It is impossible to complete divorce the HTML from the view. And the HTML ALSO (partially) defines the interface for receiving data from the user, in conjunction with the browser. And CSS can modify that interface as well. And I think if CSS is being used to store information about images, it can be considered to contain model data.
"The controller decides what the user's input was, how the model needs to change as a result of that input, and which resulting view should be used."
I don't think this is accurate either. As I understand it, the controller is an interface between the user and the view. The view decides how to change the model, not the controller.
I think for a bunch of people reading a programming blog many of you
fail to see the abstraction that Jeff is trying to point out
I, for one, understand the abstraction; I've been using it for years. However, his example is flawed
But HTML models a Document. CSS doesn't model anything, it only
describes how the HTML is presented. A "presentation filter" as Trygve
I disagree. CSS is not a View in the MVC sense.
The very first sentence of the definition of a View is:
"A view is a (visual) representation of its model"
CSS is not any sort of representation. I can even override certain elements of it with my browser settings - does that also make the browser the View? It's supposed to be the Controller in this example.
Also, how does a Controller talk to CSS if it's a View? Nothing ever talks to the CSS, it's just data (which is why I put it in the Model).
In MVC there is an interaction between the various parts (although IMO it's better if the View never calls the Model directly). CSS never interacts with anything. It is never a representation of the model, visual or otherwise. Instead it is used to create a visual representation.
The problem here is that the example is flawed, and the 3 things Jeff listed do not map to the MVC pattern. So while HTML could be considered (part of) the Model, the other bits don't fit neatly.
The conversation about fitting View properties into MVC is interesting, but too long for here.
I'm new to programming. In school, we were hammered on 3-tier. MVC was discussed as more a philosophy than a practice. 3-tier was the way MVC was implemented in RL. Is this an accurate or fair assessment?
Thanks, that was a simple, but very helpful explanation for those of us who aren't OO masters!
It's a little dangerous to say that the controller is the brains, especially to people who are not steeped in the Smalltalk way of thinking.
A lot of an application's brains should actually be in the model. Large controllers and skinny model objects are a sign of what Martin Fowler calls the Anemic Domain Model antipattern, where your model objects verge on structs, and a lot of domain logic is in the controllers or in function libraries.
The solution, pushing a lot of behavior back into model objects, is well explained in the book Domain Driven Design by Eric Evans.
Remember, kids! Object = data + behavior. If your data and behavior are separate, then you're not doing OO programming even if you're using an OO language. Instead, you're doing "procedural object-oriented programming", or POOP.
I think the best web based example one can make of MVC (in a true stateless web environment) is this
Controller: Application Server
The data being passed around with this is not that important... but what is relevant is that the user interacts with the browser, which sends messages to the application server, which updates the database, and then sends new model data to the browser to be rendered.
The most thorough description of MVC that I have found is in the book A System of Patterns by Buschmann, et al. This is the book that provided me the 'Aha!' moment where I finally grasped that MVC does not imply that any of these layers should not collaborate with both of the others. It is more about segregating the responsibilities of each layer and defining some rules about the work each performs.
If only CSS didn't suck...
When I was studying computer science, we were told a completely different kind of MVC. Especially what controller and what view is seems to be swapped in your example.
The model helds the data to work with. The model could be a database table, it could be a piece of memory with data or in many cases in modern apps, it is an object with instance variables and methods to work with those variables and the object properties as a whole.
So far describing HTML as model seems accurate. But ...
The View presents the data to the user. The view interacts with the user. The view is stupid. It does not understand the data. It does not even know how to display the data correctly: It needs to be told how to display the data and how to prompt the user for input! Basically a browser window with a simple render area in the middle and some menus is a view.
So if this webpage is a model, the browser you are using to view it is ... a view (hence the name view, you "view" the data with it).
The controller is the one who understands the data and relationships between different data types. It has all the logic, all the knowledge. And it knows what to tell the view, so the view can display certain part(s) of the data if requested and return user input if desired, which the controller will take care of to handle.
We could argue days which perspective of MVC is better, your one or mine. However, mine pretty much covers with what Wikipedia says :-P Have a look at the Pattern Description and how the three terms are explained there:
[quote] "you've probably gotten your model's chocolate in your view's peanut butter" [/quote]
This is probably a bad analogy, because chocolate + peanut butter is a good thing. I'd suggest the edit:
"you've probably gotten your model's taco seasoning in your view's Miller Lite"
You can have taco seasoning and Miller Lite at the same time, but they need to be separate.
Other than that, good article :)
I really must get around to messing about with XCode and Interface Builder properly. I am spoiled by Delphi and latterly VS2005's WinForms designer and the sugary ability to double-click on the button to tell the app what to do when the button is clicked.
Not to be pedantic, but what exactly do you mean "skinnable?" Are we talking about the Winamp Classic style of skinnable, where you can manipulate the style to your heart's content but the layout of controls stays pretty much the same, or the Winamp Modern style, where you can literally rearrange everything into a brand-new design?
Does skinnable mean that you change your sidebar navigation model to a multi-level tab implementation, or is it sufficient separation of concerns as long as you can change the banner and font sizes without turning the entire page into a hideous mess?
I've seen MVCs that I would hardly call skinnable... and I've seen lots of skinnable apps and sites that definitely aren't built on any MVC template.
Not sure if you can compare 3 tier or N tier architecture versus MVC.
MVC is representation of data via a patern where the same data can be viewed different as manipulated by the controller, where 3 tier or N tier architecture is a method of separating out different layers or coding. MVC could use 3 or n tier architecture coding pattern if needed.
MVC may be used when you have a part or parts of your system that will need to be represented with different views or different reprsentations.
For example, I want to view object X as a:
As a Thumbnail
As a node in a tree
As a preview
As a 3D image
I wouldn't get too strung out over MVC, just because your application implements it doesn't mean it is better or bug free. MVC adds abstractions to the code which is general make it more difficult to understand. Implementing MVC in your application depends on the need to represent the same underlying data structure with different views. If you don't have that requirement, then why consider implementing MVC?
This is one of the best things I've read this year. We could replace most of the MVC chapter in Head First Design patterns with this blog post and it'd be an improvement.
Where's the donate button on your blog? I want to pay for this content.
I'm also happy to see that you're checking out ASP.NET MVC and looking forward to any other reactions you have to it.
You chose a very poor CSS "controller" for your example ;/
It took me some time to get my head around MVC. It's actually several patterns together. But once you start to use it it all drops in place,
this is only an article to comment that MVC can be interpreted of several ways. If our web application is skinable is the first step to make your application structured acording to MVC but it depends of your framework if we use Zend the model is included.
your example of Model = HTML,view = CSS,Controller = Browser is bad.
Hans this is not a masturbation article.
This may be an old post, but it was quite an interesting read on MVC, which I had only recently started reading about. After a thorough read through all the comments, I've come to a rather simple, but viable conclusion about how the MVC can be interpreted safely. I will however 100% agree that the concept is open to interpretation. So here's my view:
The Model can be viewed as your database itself, with the information in it, along with the server-side code whose sole job is to retrieve, update and alter subsets of that stored information. This could include also and low-level business logic that would be commonly or regularly performed on the data before being used.
The Controller would essentially be the middle man between the Model and the View, whose job is to respond to user interaction, decide what the interaction was, decide how to handle it, and what to do with the information/interaction retrieved from the user. The Controller would take that information and often contact the Model to either update, or retrieve a subset of data based on the user's interaction. The Model would respond with the appropriate subset or possibly no subset if it was an action query of some sort, and return control to the Controller. The Controller would then take that subset of data, if available, and direct the user to the appropriate View, where the data can be presented to the user.
I stumbled upon a set of classes I used in part to complete a school project from which you instantiate a few basic PHP Objects: The Database Object, The Session Object, and the Form Object. Also, there was a controller.php page that intercepted all form submissions and utilized any Controller Objects as needed. The Controller objects would in turn communicate with the Database Object.
A user would be presented with a Registration Form. Upon submission, as with every form submission, control is directed to controller.php.
controller.php makes use of the Session Object's "Register" Method. This method would validate the user's input, build the Form Object with Input Values and Errors. If no errors were found, control is directed to the appropriate Method in the Database Object.
The Database Object would update the user table with the new values, and return control to the Session Object, giving it a response of Success or Failure.
If the update to the Database was successful, the Controller would decide which View to present to the user, along with a "Registration Successful" message. In this case, control would likely be directed back to Registration page.
The Registration page would take the Success message it received from the Controller and display it to the user, and most likely hide the registration form. From here, the process starts over based on the users next interaction.
So as a conclusion, the MVC is no more than a documented structure on which most good programmers already develop applications. So the separation concept behind it is not an unfamiliar one at all. It is a great concept and can be effectively implemented in MOST applications, but not all. The advantage, as I see it, is the ability to present a developer with a Programming Paradigm to keep in mind as he/she develops their application. If the developer follows a similar sort of structured separation, they will inevitably end up with more easily maintainable and scalable code. That being said, the programmer is not limited to this exact flavor of MVC, but rather can build his/her own conception of this sort of separation and as long as it results in organized, scalable and maintainable code, I'd say the odds are good of it representing a Valid form of MVC.
So if this thread is still even remotely alive, please let me know what you folks think of my interpretation. Keep in mind that I've only been programming for about a year if destructive criticism comes to mind ;-P - Zach
IT seems only limiting to me, that we wish for development to have a standard model like MVC. I guess in if we don't mind leaving our imaginations out of it, then it would be nice to nail down a concept like MVC; we could go about our development with confidence that the correct approach was taken and professional job was done. This way we don't have to toil over figuring out a tailor made model for each new application we build. By trying to define best development strategy in terms of some fundamental model like this MVC, I believe we impose great and unnecessarily restriction upon the possibilities. Perhaps views should be smarter and control more static? Maybe I want to alter your model with my app's view? Perhaps I need my controller to be dynamically generated based on the nature of your view. Now your view would serve as my solution's model and promote my controller into service as a view. Maybe this smart, on-time view of mine could now model for some other app's controls. Perhaps we could come up with a new way to aggregate application functionality regardless of API or even in the absence of one. But, no such fun is likely to happen, if we've accepted a restricting "best standard" for our work to feel professional.