21

I'm trying to learn the MVC pattern, but each place say something different. So now I don't know whats the true MVC.

So I'm guessing its the most pure MVC:

  • Model is just data and notify data changes.
  • View reads the messages of the Model to update the view.
  • Controller reads the user input from View and changes the Model according.

Implementing

  • Model knows no one.
  • View knows the Model.
  • Controller knows both View and Model.

Pseudocode:

/* Model */
class Color{ 
  color = blue;
  setColor(color);
  notifyUpdate();
}
/* View */
class ColorPicker(model){
  model.register(update);
  update(){
    this.colorToExhibit = model.color;
  }
}
/* Controller */
class Colorize(view, model){
  view.register(update);
  update(color){
    model.setColor(color);
  }
}

Some questions:

  1. Is that right?
  2. I can't see why the View cannot change the Model directly, but through Controller.
  3. Suppose I have animations to be performed after an action. Who must handle this animation: the Model, the View, or the Controller? Also: the animation logic is part of the Model, View, or Controller? More: Suppose a Poker game. After the user choose an action (say, 'Raise'), the system must play an animation (say, the chips going from player spot to the desk). How can I see this poker example (with animation) as a MVC? Can you explain and give a pseudocode about that?

Thank you.

halfer
  • 19,824
  • 17
  • 99
  • 186
Fabricio
  • 7,705
  • 9
  • 52
  • 87
  • 1
    http://st-www.cs.illinois.edu/users/smarch/st-docs/mvc.html – Esailija May 27 '12 at 13:22
  • I suspect the reason you're finding different places 'say something different' about MVC is that there are differences in implementations. David's excellent answer sounds specific to iPhone development, for example - the concept of a view "binding" to a model isn't a descriptive term I recognise from PHP web MVC systems such as symfony. Equally, models don't have to raise events in a theoretical MVC system, though they do in Objective C. Your best bet I think is to pick up an MVC system and play with it. Are you looking to do mobile/application development, or web stuff? What language? – halfer May 27 '12 at 14:06
  • @halfer: Actually, I've never done iPhone development. My primary experience is web development, and I was trying to make an effort to separate the description from the ASP.NET MVC implementation. I guess that effort met with some success :) By "binding" I don't mean anything language/framework-specific, but rather just having a skeletal View which expects Model data in specific spots. The act of "binding" would be to populate those spots. Frameworks have different tools to do this, or it can be done manually. – David May 27 '12 at 14:15
  • @David, thanks. Indeed, data is made available by the controller to the view - imo this need not just be model data, but could equally be calculated, randomised, literal, cached data (etc). The main point I'd make to Fabricio is that not all variables used in the controller logic are available in the view - in general the programmer specifies what to make available, so the interface between the two is clean and well-defined. In my (PHP) experience the view cannot independently see the model, unless the controller supplies a column value, row class or result collection (etc). – halfer May 27 '12 at 14:37
  • @halfer: All good points. I usually prefer to have a distinction between "Model" and "ViewModel" in this regard. The Model is the business domain object. In many cases this is one-to-one with UI behavior, but not always. And even when it is, it's still a different concern. The ViewModel would contain any View-specific transforms of the data as well as any View-specific functions to be performed on the data. In this regard I like the FubuMVC approach of "exactly one ViewModel to the View, exactly one ViewModel back." Having a thin UI-bound ViewModel is very useful for these purposes. – David May 27 '12 at 14:46
  • Strange ... at this point in time, there are three answers all by a David... – D.Shawley May 27 '12 at 16:45

3 Answers3

27
  • Model is just data and notify data changes.
  • View reads the messages of the Model to update the view.
  • Controller reads the user input from View and changes the Model according.

The Model is more than just data. The model is also the business logic. It contains all of the intelligence of the system, or at least an abstraction of behind-the-scenes intelligence (such as database calls or other service calls). Consider the saying, "Keep your models heavy and your controllers light."

  • Model knows no one.
  • View knows the Model.
  • Controller knows both View and Model.

The Model knows no one, that it correct. The Model should be portable between applications and shouldn't depend on UI concerns in any way. (The View and the Controller are UI concerns in this case.)

The View knows the Model, also correct. The View basically "binds" to the Model. It presents all of the UI elements and places Model data within the UI elements accordingly.

The Controller kind of "knows the View." It knows which View to which it should direct control, but it doesn't know anything about that View. Nor does it know which View from which control previously came. The Controller responds to events. An event comes in from the UI, carrying some kind of state information with it (a ViewModel, perhaps), directs logical control through the Models (where the business logic happens), and responds with a Model (or a ViewModel, if the shape of the data specific to a particular View is different than the Models) and a View.

I can't see why the View cannot change the Model directly, but through Controller.

The View can manipulate the Model within the context of the user interaction, but shouldn't expect those changes to persist in any way. The View should be considered "client-side" and doesn't know anything "server-side." (Even if you're talking about a native application and not a web application.) Persisting any change is considered a UI "action" or "event" and would go to a Controller to make it happen.

Suppose I have animations to be performed after an action. Who must handle this animation: the Model, the View, or the Controller? Also: the animation logic is part of the Model, View, or Controller?

An animation sounds like an entirely UI-based operation. It would be within the View. Is there more happening than just a UI animation? Does the animation change anything in the back-end? For example, if I have a web application and, when a page loads, I want to fade-in some data (an animation)... that's entirely in the View. The data would be delivered to the View like any other data, and the animation takes place entirely within the UI (View). It doesn't do anything from the perspective of the Model or the Controller.

Suppose a Poker game. After the user choose an action (say, 'Raise'), the system must play an animation (say, the chips going from player spot to the desk). How can I see this poker example (with animation) as a MVC? Can you explain and give a pseudocode about that?

The action ("Raise") is a Controller event. The UI would contact the controller to perform the "raise". So the Controller might have a method like this:

View Raise(GameState state)
{
    // Interact with the Models to update the known state of the game.
    // The Models would perform the actual Poker game logic.
    // Respond with a View bound to updated Models.
}

Once the Controller responds to the UI with a new View, that View would contain any animations to display to the user. (After all, you don't want to perform the animation unless the action was successful, right? When the Controller responds to the UI with a new View indicating a successful action, then the animation would play. It may instead respond to the UI with a View indicating an error, in which case that View would show something else.)

David
  • 208,112
  • 36
  • 198
  • 279
  • I'm a little confused about the controller "kind of" knowing about the view. What do you mean by "which View it should direct control"? Can you elaborate? – B T Feb 25 '14 at 09:05
  • @BT: The controller is kind of a coordinator/dispatcher. It receives a request or some input of some kind, interacts with the models to change system state based on that input, and directs output to a view. So it "kind of" know about the views in the sense that it needs to know which one to direct as output. The view being rendered as output, conversely, does not know anything about the controller which just rendered it. The flow from controller to view is one-way. – David Feb 25 '14 at 10:56
  • Ok, so when you're talking about a view, you're talking about a whole screen/page that is either showing or hidden, right? Can that concept be generalized to composite views? – B T Feb 25 '14 at 20:23
  • @BT: Ultimately the view is the UI presentation that's rendered to the user. Whether it's composed of multiple components, whether it has shown/hidden components, etc. is all a matter for how you decide to construct the view. Different technologies/frameworks/etc. will approach those concepts in different ways. But the end result is some kind of interactive interface for the user. Conceptually that is the view, physically that view may be composed of many different elements, any one or more of which may be called a "view" in its respective technology. – David Feb 26 '14 at 00:00
18

I'll go with the simple Bank analogy.

  • Tellers are Views.
  • Runners are Controllers.
  • Bankers are Models.

The Bankers are the smart ones, they know all of the business logic and do all of the complex calculations.

The Runners are used to transport the money (data) from the Bankers to the Tellers.

The Teller presents the money to the Customer.

A simple representation:

Model

public class BankAccount
{
     public int ID;
     public int Balance;

     public BankAccount(int id)
     {
         ID = id;
         Balance = DetermineAmount();
     }

     public int DetermineAmount()
     {
         // Gather transaction info, debits, credits and return a
         // sum of the amount left in the account depending on the
         // id provided.
     }
}

Controller

    public class BankAccountController
    {

         public ViewResult Index(int id)
         {
             BankAccount account = new BankAccount(id);
             return View(account);
         }

    }

View

<ul id="account-info">
   <li>Account ID: `@Model.ID`</li>    
   <li>Balance: `@Model.Balance`</li>
</ul>
David East
  • 31,526
  • 6
  • 67
  • 82
9

If you are interested in the historical true MVC, then start with Trygve Reenskaug. He created (observed?, catalogued??) it in the late 1970s. For a start, read "Models-Views-Controllers" from 1979. It defines the terminology. Take careful note of it's title - all three roles are pluralized. This is the first thing that most people seem to get wrong.

The best description I've found of the original use of MVC is actually in a presentation dated 2004 entitled "Inside Smalltalk MVC". I would guess that the canonical papers that describe the Smalltalk 80 final version of MVC are Krasner & Pope's "A Cookbook for Using the Model-View-Controller User Interface Paradigm in the Smalltalk-80" and Steve Burbeck's "Applications Programming in Smalltalk-80: How to use Model-View-Controller (MVC)". Both papers are well worth the read.

If you have some time to kill and don't mind listening to Robert Martin, he did a good keynote at Ruby Midwest 2011 that touched on MVC. It is a little over an hour, but quite entertaining and enlightening. I tend to follow with his opinion that most implementations get MVC wrong. I spent a little time looking around and finally found a diagram that I can link to which describes MVC. The one that I like came from Pope and Krasner.

MVC
(source: as3dp.com)

From my point of view, the following are the key points:

  • a model instance is responsible for notifying the interested objects of changes. Note that these can be any object instances. The diagram shows both views and controllers receiving updates here.
  • views are responsible for querying the current state and displaying the results. They usually perform filtering or data transformation as well.
  • controllers are responsible for accepting user input and forwarding view messages along to the view.
    • View messages are a common theme in MVC. It is important that these are independent of the UI world - these are not mouse clicks and what not but a view-specific language of events. This brings us to the next point.
  • The view does not depend on the controller in any way. Controller's are responsible for arranging and creating views and providing the interface between the rest of the world and the view.
  • In a perfect world, the view is responsible for making the model representation visible. This is how it worked when MVC was applied to desktop applications.

The reality is that MVC has been twisted and rewritten for the web world. It's not really MVC anymore or maybe MVC was simply redefined. This is why you are seeing so many different opinions and representations of MVC out there. If you are looking into writing desktop style applications, then look at the stuff by Krasner & Pope. If you are looking into how MVC is applied to the web, then I recommend Uncle Bob's keynote for an alternative that it better suited for web applications - what he called the Interactor, Entity, Boundary Architecture for lack of a better name. Dig around for stuff associated with his talks about "the Lost Years of Architecture".

Community
  • 1
  • 1
D.Shawley
  • 58,213
  • 10
  • 98
  • 113