views:

613

answers:

11

I am having some trouble understanding the MVC Pattern. I do understand we are trying to decouple the GUI from the business logic, although I'm having problems understanding how.

From what I understood, the View, is what the user sees. So it generally is the window/form. The Controller is inbetween the View and the Model. The Controller will make the data "flow" in both directions. It will also persist state when needed (if I have a wizard with 5 steps, it is the Controller's responsability to ensure they are made in the correct order, etc). The Model, is where the core of my application logic lives.

Is this view correct?

To try to turn this into something more meaningful, I'll try to sketch out a simple example with WinForms(no ASP.NET or WPF, please! - to the java crowd, from what I come to understand, Swing works in a similar way to WinForms!), to see if I get it right, and I'll raise the questions I always come to while doing it.


Let's assume I have a model that contains just a class (just to make it easier. I know it will make the example look dumb but its easier this way):

class MyNumbers {
    private IList<int> listOfNumbers = new List<int> { 1, 3, 5, 7, 9 };

    public IList<int> GetNumbers() {
        return new ReadOnlyCollection<int>(listOfNumbers);
    }
}

Now it's time to make my Controller:

class Controller
{
    private MyNumbers myNumbers = new MyNumbers();

    public IList<int> GetNumbers() {
        return myNumbers.GetNumbers();
    }
}

The View should just have a ListBox that has as items all the numbers retrieved in MyNumbers.

Now, the first question arises:

Should the Controller be responsible for creating MyNumbers? In this simple case, I think its acceptable(as MyNumbers will do exactly the same, no matter what, and has no associated state). But let's assume I would want to use for all the different Controllers my app has the same instance of MyNumbers. I would have to pass to this Controller(and all others that need it) that instance of MyNumbers that I want to use. Who is going to be responsible for that? In this WinForms examples, would that be the View? Or would that be the class that creates the View?

Turning the question around: what is the order of instantiation of these 3 parts? What is the code that the "owner" of the MVC called to create it? Should the Controller create both the View and Model? Should the View instantiate the Controller and the Controller the Model?

Second question:

How is the main method supposed to look like, assuming I only want my application to have the Use Case this Controller portrays?

Third:

Why does in the following MVC diagram, the View have an arrow to the Model? Shouldn't the Controller be always the bridge between both View and Model?

alt text


I'll have one or two more questions, but they probably will make more sense asked after I understand this first detail. Or maybe after I understand that first question all the others tear apart.

Thanks!

+1  A: 

"From what I understood, the View, is what the user sees. So it generally is the window/form. The Controller is inbetween the View and the Model. The Controller will "handle" data in both directions. It will also persist state when needed (if I have a wizard with 5 steps, it is the Controller's responsability to ensure they are made in the correct order, etc). The Model, is where the core of my application logic lives."

This is almost correct. The controller doesn't persist data. It calls a service that persists data. The reason is, persisting data is never just a call to save. You might want to do validation checks on the data to make sure it is sane according to your business needs. You might want to do some authentication to make sure the data can be saved by a user. If you do that in a service, then you have a nice bundle of functionality that you can use over and over again, say for a webapp and a web service. If you do it in a controller, say for a web app, when you go to write your web service you will have to refactor and/or duplicate code.

In response to your comment "I am not sure I totally understood your point. Does the Controller check UI input, or is the Model that does it?"

You controller should only control which business functionality paths get executed. Thats its. Controllers should be the easiest part of the code to write. You can do some validation on the gui (i.e. view, e.g. like making sure email addresses are properly formatted, text inputs dont exceed maximums), but the business layer should also validate the input -- for the reason I mentioned earlier, that when you start standing up more endpoints, you don't have to refactor.

hvgotcodes
I used the incorrect term when said "handle". I meant not to "work" with it, but just make it flow, from the View to the Controller, and Controller to the View.
devoured elysium
I am not sure I totally understood your point. Does the Controller check UI input, or is the Model that does it?
devoured elysium
sure. I think you get it. My comments were more about how to use MVC with some common design choices that allow you to write reusable components. You know you are doing it wrong if your model is handling view concerns (like outputting html), or you controller is handling business logic (like deciding how to format values to be saved), etc....
hvgotcodes
A: 

I do not understand why your asking for this information when wiki provides it all?

http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

RobertPitt
So basically you are asking why does Stackoverflow exist when "wiki provides it all"...
devoured elysium
+1! Stackoverflow vs a Wiki.... that could be a whole new discussion!
gnome
SO is already a wiki concept. and my point was that every post on here will be described on wikipedia, so to save hassle read the page thats already out there. then if you have any in depth questions come ask.
RobertPitt
So I guess "where to start C#" fits in as a "in depth question", I suppose?
devoured elysium
That article is no more useful than the flowchart! Question is 'what does the actual code look like?' All these fancy patterns, no proof the writers have done it. That is the elephant in the room about all n-layer design discussions. If you want me to trust you know what you're talking about, SHOW ME THE CODE! I know that's not what wikipedia is for, though.
FastAl
Where to start with C# was a very good question in fact, it was more along the lines of what software do I need, where's the best place to to get started, tips etc. I laughed at you going threw my posts and trying to find something against me :). Childish infact. if you read my post I said "I do not understand why your asking for this information when wiki provides it all" is giving him the answer to his question whilst infact asking a question myself. I was not disrespecting SO, or the OP. Just answering a question and asking one in turn.
RobertPitt
+2  A: 

Answer to the third question:

When the model changes, it notifies the view, then the view gets the data from the model using its getters.

Zoltan Balazs
is this a question or a statement?
hvgotcodes
sorry, the answer :)
Zoltan Balazs
But aren't we adding unneeded coupling between the View and the Model? Shouldn't we just use the Controller as a kind of proxy? Who has the responsability of turning the IList<int> data to items in the ListBox? The View or the Controller? Should the Controller show to the View the IList or should it for example, have a reference to the ListBox and adds things to the ListBox itself? Thanks
devoured elysium
Let's see an example:You have important data and you want to show them to your users. So you have a model, may be a list. The view gets the list from the model, and the view knows how to show the data. The view can show it in a table, diagram, etc...
Zoltan Balazs
When you allow your users to modify the model (add/delete items) then you have a button or something and you call one of the method of the Contoller and the Controller will modify the Model. The model changes, notifies the View, the View gets the data.
Zoltan Balazs
+15  A: 

The easiest way to get a handle on MVC is to use it in a framework that enforces it, that being said..

  • The Model interacts with the datasource (DB or whatever) and gives you access to your data.
  • The View interacts with the outside world, it receives input from somewhere and hands off the data to the Controller it also listens to the Controller to make sure its displaying the correct data.
  • The Controller is where all the magic happens; the Controller manipulates data, pushes events, and handles changes in both directions (to/from the View and to/from the Model).

This diagram is very helpful (it makes much more sense than Wikipedia's): MVC Diagram

Source, and a great article on MVC!

indieinvader
Great answer (+1). Can you provide a source for the diagram?
Cam
@incrediman: from the image's URL: http://java.sun.com/developer/technicalArticles/javase/mvc/ Actually, I find the 1st image on that article more clear since it explains the responsibilities of each as well.
BalusC
So, when you say that "The View interacts with the outside world, it receives input from somewhere and hands off the data to the Controller" you mean that the Controller will have a reference to the ListBox and "hears" its events, adds its items, etc? Or it sends data up to the View and its the View itself that will add the items, etc? This question is bugging me around for some time :(
devoured elysium
@BalusC: The two diagrams are different. The first may have more information but discusses an older type of MVC implementation, so I find the second more helpful.
Cam
The Controller will have a reference to ListBox and updates the Model when things change. (The View never stores anything, it only sends messages)
indieinvader
@incrediman: Ah, yes, you're right! I'm reading the article and yes, the two diagrams are different. So my idea of having the Controller mediate data flowing from the View to the Controller fits correctly in this second diagram.
devoured elysium
@indieinvader: ahh! that was one of the pieces missing. I always thought that it would be the View to have that job.
devoured elysium
Glad I could be of help! MVC can be tough to get your head around but once you get it you'll find that it helps tremendously, _especially_ as your projects start growing you'll find that separating your code like this does wonders for their manageability.
indieinvader
Nice refresher!!! on MVC concepts (+1) for the useful link
StudiousJoseph
+1  A: 

This is from Java, but hopefully it will help.

For the main:

public static void main(String[] args) 
{
       MyNumbers myNums = new MyNumbers();  // Create your Model
       // Create controller, send in Model reference.      
       Controller controller = new Controller(myNums); 
}

Your controller needs a reference to your model. In this case, the controller actually creates all the Swing components. For C#, you may want to leave the form initialization here, but the View/Form needs a reference to the Model (myNums) and the Controller (controller). Hopefully some C# people can help on this front. The View also needs to register as an Observer of the Model (see Observer Pattern).

Here is the constructor I have (adjusted for your case):

public NumberView(Controller controller, MyNumbers myNums)
{
      this.controller = controller; // You'll need a local variable for this
      this.myNums = myNums; //You'll need a local variable for this
      myNums.registerObserver(this); // This is where it registers itself
}

The View passes the work to the Controller to handle the user's actions (buttons, whatever). The Controller decides what to call/do in the Model. In general, the Model then does something and changes its state(maybe more numbers in your list. Whatever it does). At the point, the Model will let its Observers know it has changed and to update themselves. Then the View goes and gets the new data and updates itself. That is why the Model and View talk (your 3rd question).

So the Model will have:

public void notifyObservers()
{
    for (Observer o: observers)
    {
        o.update();  // this will call the View update below since it is an Observer
    }
}

So in the View, you'll have something like this:

public void update()
{
    setListBox(myNums.getNumbers());  // Or whatever form update you want
}

Hope that helps. I know it is Java, but the concept still applies. You'll have to do a little reading on the Observer pattern to fully get it. Good luck!

Awaken
So, is the Controller instantiating the View?
devoured elysium
Sorry, I hit enter prematurely. Hopefully the full answer will help you. Let me know if you need further explanation on any point.
Awaken
So, first of all, as I understand it you are referring to "MVC 1", as seen on my original post diagram, as opposed to indieinvader's one, right?
devoured elysium
This is from the classic MVC I think, so I guess MVC 1. It is based on the diagram in your post. The answer is from Head First Design Patterns, adapted to my situation which happened to be similar to yours, with the Model name changed and altered slightly for your situation.
Awaken
Ah, I've never noticed Head First Design Patterns had a section on MVC!
devoured elysium
Haha. Yeah, it's in the back in the Compound Patterns section.
Awaken
Hmm, I don't understand what are the advantages of this kind of MVC. If I got it right, first of all I have to make my Model classes inherit from Observable (which is not suitable a of the times) in Java, if I want them to be observable from the View. So it is a constraint my Model classes have to have(inheriting from Observable, which from what I know in Java is a class), which seems awful by itself, as the Model should be there to represent as well as possible our business logic, without any other kind of interference.
devoured elysium
I actually don't use the Observable class that is in the Java library (because of the inheritance issue). I create my own interface called Observable (and Observer) which is almost the same thing. It is confusing when I post on the internet. Hopefully that helps it seem less "awful." It does work pretty well.
Awaken
+1  A: 

Should the Controller be responsible for creating MyNumbers?

I would say 'definitely not.'

If the MVC pattern is designed to decouple the M, V, & C elements, how can this work if the C simply instantiates the M with new MyNumbers()?

In Java, we would use something like the Spring Framework here. You need a way to express the dependency relationship -- or rather the details of how it gets fulfilled -- in a configuration file or other suitable place (i.e. not in compiled code).

But there is another element to this issue: you probably shouldn't define the myNumbers variable (inside C) with the concrete, runtime type you intend to use. Use an interface or an abstract class, and leave it open as to what the actual runtime type is. This way, in the future you can re-implement the IMyNumbers interface to satisfy emerging requirements (those you don't know today) and your C component will continue to work perfectly, none the wiser.

Drew Wills
You make good points. I want to stay away from frameworks until I understand how to implement it myself! Only after, I will look for frameworks.
devoured elysium
@devoured elysium -- you bet! I understand you provided (and want to discuss) a very simple example. But simple examples can be misleading in cases like these, if they're simple to the point where there's no longer much motivation even to use the MVC pattern. In real-world scenarios, there's plenty of justification for patterns like MVC.
Drew Wills
+1  A: 

Why does in the following MVC diagram, the View have an arrow to the Model? Shouldn't the Controller be always the bridge between both View and Model?

It is the MVC model 2. You can see it usually in Java enterprise application where CONTROL does the business as well as processes data from/to MODEL and choose which VIEW to render back to client. When rendering to client, VIEW will use data from MODEL:

alt text

Here is an example how to access data from a JSP(VIEW) file which a bean (MODEL):

class Person {String name;} // MODEL
My name is ${bean.name}     // VIEW
Truong Ha
A: 
  • View draws the model and represents it to the user
  • Controller handles the user input and translates them to the modifications into the model
  • Model holds the data and modification logic

There's no point translating it into code. You won't get it correct straight out anyway.

Cheery
+1  A: 

I will try to answer this from a relatively less technical stand for what it's worth. I'll try walk through a general example.

Controller controls what view is used. So, say, if you are writing to the page the controller will direct you to the input view (say) while if you are reading the same page it will direct you to it's success view (say).

After one writes to the page the controller will pass those parameters to the relevant model where the logic pertaining to what has to be done with them resides. If there is as error then the controller will direct you to the error view.

My knowledge is based on my one month experience with Agavi. Hope this helps.

Ashish
The end user looks at the various views at all times.
Ashish
+1  A: 

View

  • user interface / responsible with input output / some validation / needs to have a way to notify outside world of UI level events

  • knows only about the model

Model

  • data structure / represents the data that is presented / should not contain business logic (maybe only some data/structure validation at most)
  • knows only about himself (think of a Person class that has only Name and Age)

Controller

  • is responsible for business logic / it crates Views and glues the respective models onto them / has to be able to respond to View events / accesses other layers of the application (persistence / external services / business layers etc.)

  • knows everything (at least View and model) and is responsible of gluing everything together

AZ
I can't understand why the Model shouldn't contain any business logic. Shouldn't be the Model to have ALL the business logic?
devoured elysium
The model is supposed to transit multiple layers of the application logic (Data Access, Business, UI etc.). Plus it is possible to have the same model (eg. Person with all dependent data) used in multiple business scenarios. That's why it is good practice to separate the model from different business transactions / contexts.
AZ
+2  A: 

As for the criticism within my post I thought I would give a post on how i tend to create an MVC Pattern in PHP

Within PHP i spit the framework up into several sections, of witch some are the normal when it comes to MVC.

Primaries:

  • Controller
  • Model
  • View

Secondariness - ModelLayer

  • ViewLoader
  • Library
  • ErrorLayer

Within the controller I usually allow all access the secondary layers and the View and Model from Primary.

Here's the way I would structure it

|---------|       |------------|       |------------|
| Browser | ----> | Controller | ----> |   Model    |
|---------|       |------------|       |------------|
     |                  |   |                |
     |                  |   |----------------|
     |                  |
     |            |------------|
     -------------|    View    |
                  |------------|

From my diagram I usually bypass the View <-> Model connection and do a Controller <-> Model and then the link from Controller <-> View assigns the data.

Within my framework I tend to create a object storage system so that i can easily fetch objects and so forth. an example of my object storage is like so

class Registry
{
   static $storage = array();

   public static function get($key)
   {
       return isset(self::storage[$key]) ? self::storage[$key] : null;
   }

   public static function set($key,$object)
   {
       self::"storage[$key] = $object;
   }
}

Somewhat more advanced by that's the outline, so with this when I first initialize objects i store them like Registry::set("View",new View()); so that there always accessible.

So within my controller witch is the base controller i create several magic methods __get() __set() so that any class that extends the controller I can easily return teh request for example:

abstract class Controller
{
   public function __get($key)
   {
       //check to make sure key is ok for item such as View,Library etc

       return Registry::get($key); //Object / Null
   }
}

And the user controller

class Controller_index extends Controller
{
    public function index()
    {
       $this->View->assign("key","value"); // Exucutes a method in the View class
    }
}

The model will also be placed into registry but only allowed to be called from ModelLayer

class Model_index extends ModelLayer_MySql
{
}

or

class Model_index extends ModelLayer_MySqli
{
}

or filesystem

class Model_file extends ModelLayer_FileSystem
{
}

so that each class can be specific to the storage type.

This is not the Traditional type of MVC Pattern but it can be called Adoptive MVC.

Other objects such as the View Loader should not be placed into registry as there not specifically for the users interests but used by other entites such as View

abstract class ViewLoader
{
   function __construct($file,$data) //send the file and data
   {
       //Include the file and set the data to a local variable
   }

   public function MakeUri()
   {
       return Registry::get('URITools')->CreateURIByArgs(func_get_args());
   }
}

as the template file is being included in the View loader and NOT the View class it separates the user methods from teh system methods and also allows methods to be used within the views themselves for general logic.

Example of template file.

<html>
   <body>
      <?php $this->_include("another_tpl_file.php"); ?>
      <?php if(isset($this->session->admin)):?>

          <a href="<?php echo $this->MakeUri("user","admin","panel","id",$this->session->admin_uid) ?>"><?php echo $this->lang->admin->admin_link ?></a>

      <?php endif; ?>
   </body>
</html>

I hope my examples help you understand that little bit more.

RobertPitt