16

I've got an app which uses MVC, but I'm struggling a little as to how the controller should be architected. For example, the View is only viewing some subset of the model's data at once. However, I'm unsure as to exactly how this should be arranged. Is it normal for the View or Model to directly call functions on the Controller, for example? Through some sort of interface? Or are they totally encapsulated and never know about the Controller or each other?

Just as an edit; this is a custom app not written in any web framework, so I'm not looking for framework-specific details here and have the freedom to make my own choice.

4
  • 1
    I won't answer because my experience is limited in MVC architectures, but from all I've heard and talked to others about, the M&V are tightly coupled to each other but not the C. The M generally calls functions on the C and the V often only databinds to some subset of the M. May 12, 2012 at 20:13
  • 8
    @SnOrfus: That's exactly opposite to what I thought- the M & V are coupled to the C but not to each other.
    – DeadMG
    May 12, 2012 at 21:43
  • 1
    How can so many answers be so wrong. Here read MS's version msdn.microsoft.com/en-us/library/ff649643.aspx
    – Reactgular
    May 13, 2012 at 15:56
  • Give this article a read: objectmentor.com/resources/articles/taskmast.pdf May 13, 2012 at 19:56

7 Answers 7

15

The controller controls the flow of activity. The user performs this action, the controller passes the view data to the domain which does whatever it needs to do then, based on the response(s), the controller tells the framework which view to show next (and gives it enough data to do so).

The controller must thus be coupled to the domain model, to some extent. ie. You could put a service layer in between but, by strict definition, that becomes part of the domain.

It is also coupled to the view data but not the view itself. ie. it simply says "show the customer view using this customer detail." The framework then decides where it should find that view.

Now this should allow you to decouple the domain model from the view, by using a view model of the same data. Some developers do this, some don't, and I do think it's largely a matter of personal preference.

In Rails, you are very much encouraged to push the domain objects (ActiveRecord) to the view and trust that the view doesn't take advantage of that access (eg. you shouldn't call customer.save from the view, even though it would be available).

In the .NET world, we tend to reduce risk by not allowing things that shouldn't happen and, possibly for that reason, it seems to me that the detached view model is more popular.

1
  • 1
    View model is a very common practice when it comes to unit testing. You would normally auto map domain model or a DTO object to a view model. You would then use your view model in a view. View model is easily testable and it's not tied to a layer below.
    – CodeART
    May 13, 2012 at 16:16
7

Note: Robert C. Martin (aka Uncle Bob) explains this in a much better and humorous way in his keynote, Architecture the Lost Years. A bit long but teaches lots of good concepts.

tl;dr: Don't think and plan your app in terms of MVC. The MVC framework is just an implementation detail.

The most confusing thing about MVC is, developers tries to use all the components glued together.

Try thinking in the terms of a program, not in the terms of the framework.

Your program has a purpose. It takes some data, does things with data, and returns some data.

That way, the controller is the delivery mechanism of your program.

  1. A user sends a request to your program (let's say, add a product to the shopping cart).
  2. The controller takes that request (product info and user info), it calls the necessary part of your program that will handle this request $user->addToCart($product)
  3. Your program (addToCart function of the user object in this case) does the work it's intended to do and returns a response (let's say success)
  4. The controller prepares the response using the relevant view: eg. in the controller object $this->render($cartView('success')

This way, the controllers are decoupled from the program, and used as delivery mechanism. They don't know how your program works, they just know which part of the program need to be called for the requests.

If you want to use another framework, your app won't need a change, you will just need to write relevant controllers to call your program for requests.

Or if you want to make a desktop version, your app will stay the same, you will just need to prepare a delivery mechanism.

And the Model. Think of it as a persistence mechanism.

In the OO way, there are objects in your program that holds the data.

class User {
    //...
    private $id;
    private $shoppingCart;
    //...
}

class Product {
    //...
    private $id;
    //...
}

When you add a product to the shopping cart, you can add the the product::id to the user::shoppingCart.

And when you want to persist the data, you can use the model part of the framework, which generally consist using an ORM, to map the classes to the database tables.

If you want to change the ORM you use, your program will stay the same, only the mapping information will change. Or if you want to avoid the databases all together, you can just write the data to plain text files, and your app will stay the same.


So, write your program first. If you programming with the 'OO' way, use plain old objects of the language. Don't think in terms of MVC at first.

2
  • Great video. Thanks. I would disagree with your interpretation of it though. MVC isn't a detail in the meaning that Uncle Bob has there. You'll note that MVC is an architectural pattern much like his "Interactor/Entity/Boundary" pattern he's establishing. On the other hand, any particular MVC system, such as Spring or whatever, is indeed something he's recommending to defer. As he explains though, these frameworks being called "MVC" is sort of a bastardization of the term. May 13, 2012 at 19:16
  • Yea, I wrote that in the way that people think what a MVC is. That's why I wrote MVC Framework. May 13, 2012 at 19:45
2

Martin Fowler does a good job of describing the MVC paradigm. Here is a link to his article on it http://martinfowler.com/eaaDev/uiArchs.html

Note his quote about Separated Presentation "The idea behind Separated Presentation is to make a clear division between domain objects that model our perception of the real world, and presentation objects that are the GUI elements we see on the screen."

1

Here is a simple example of how MVC can be used in a typical Java Swing application ...

Let's say you have a Panel containing a Button and a TextField. When the Button is pressed, an event is fired, leading to some state change in the application. Once the state change is registered, the TextField becomes disabled.

This, then, would be the typical approach taken by a simple MVC application ...

The Controller registers itself as the listener of the View's events. When the Button is clicked, the View itself does not handle the event; the Controller does. The Controller is Swing specific as it must deal with Swing related events.

The Controller receives this notification and must decide who must handle it (The View or the Model). Since this event will change the state of the application, it decides to forward the information to the Model who is responsible for data and program logic. Some make the mistake of placing program logic in the Controller but in OOP, Models represent both data AND behavior. Read Martin Fowler on his take of this.

The message is received by the Model in the proper context. That is, it is completely void of any reference to Swing or any other GUI specific references. This message speaks to the Model and ONLY the model. If you find yourself importing javax.swing statements in the Model, you are not coding the Model correctly.

The Model then sets its state to 'disabled' and proceeds to notify any interested parties of this model change. The View, being interested in this event has already registered itself as an Observer of any model changes. Once the Model state change event is picked up by the View, it proceeds to disable its TextField. It is also legal for the View to get Read-Only information directly from its Model without having to go through the Controller (usually through a specific interface exposed by the Model for such activity)

By promoting such loose coupling between the Presentation and Business Logic and Data Layers, you will find your code is much more maintainable. As systems grow, so too will your approach to MVC. For example, Hierarchical MVC is an extension often used to link MVC triads together to form large enterprise wide systems without coupling subsystems together

0

Coupling (the sort you want to avoid) involves a mutual dependency between two classes. That is, a Foo depends on a Bar and a Bar depends on a Foo so that you can't really modify one without modifying the other. That's a bad thing.

You can't really avoid having SOME dependencies, however. Classes have to know a little bit about one another, otherwise they'd never communicate.

In the MVC pattern, the Controller controls communication between the domain Model and the presentation View. As such, the Controller must know enough about the Model to ask it to do what it's supposed to do. The Controller must also know enough about the View to be able to present it to the client or users. So, the Model Controller has dependencies on both. However, the View can exist perfectly well without the Controller--there is no dependency there. Likewise the Model has no depencies on the controller--it simply is what it is. Finally, the Model and View are completely separate from one another.

Essentially, the Controller is the level of indirection that decouples the View from the Model, so that they do not have to know about one another.

1
  • Ah--that's why the downvotes--I miswrote. I meant the Controller has dependencies on both. D'oh! May 13, 2012 at 18:17
-5

In my experience, generally the model only depends on a view, not a specific one, often as an observer...if it has any such coupling at all.

The view generally couples to whatever it's looking at, which makes sense. Hard to come up with a view that could be decoupled from what it's viewing...but sometimes you can have a partial coupling or something.

The controller often tends to couple to both. This also makes some sense since it's job is to turn view events into model changes.

Of course, this is only a tendency I've observed and doesn't really say anything about any specific example.

To understand what MVC is and what the coupling relationship tends to be you should look into how MVC came to be. The environment in which MVC was created was one in which "widgets" as form elements you can build dialogs with did not exist. A "view" was a box and it drew stuff. A text view would be a box that would draw text. A list view was a box that would draw a list. The "controller" received all mouse and keyboard events from the UI system that took place in that view; there were no "textChanged" or "selectionChanged" events. The controller would take all these low level events and generate interaction with the model. The model, upon being changed would notify its views; we have since come to see this relationship as "observer" and it's used in other ways as its own pattern.

THAT is the essence of the MVC pattern. Since this kind of low-level UI programming is generally not done anymore, the MVC has evolved in many different directions. Some things that go by that name today are hardly anything at all like the MVC and should really be called something else. It can still be used though in the sense of a dialog as a whole interacting with a larger object. There's many better alternatives though.

Basically, everything the MVC was meant to solve happens inside of widgets now and is something we no longer have to use.


For those that think they know better:

http://www.codeproject.com/Articles/42830/Model-View-Controller-Model-View-Presenter-and-Mod

http://msdn.microsoft.com/en-us/library/ff649643.aspx

I'm sure there are more but those are just the top of the list in google. As you can see, the model very much depends on a view interface in MANY implementations. Generally a model is observable and the view is an observer.

But why let facts get in the way...

An article already posted in another answer also supports my statements:

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

If people want to continue saying that EVERYONE in the design industry is wrong then that's fine.

16
  • 4
    This is plainly wrong. A model mustn't depend on a view ever! Even if that view is abstract or an interface. A model ought to be fully decoupled from the presentation!
    – Falcon
    May 13, 2012 at 8:18
  • 3
    Answer is wrong. Model does not depend on a view or controller.
    – CodeART
    May 13, 2012 at 15:35
  • 2
    @Crazy Eddie You said: "In my experience, generally the model only depends on a view, not a specific one, often as an observer" Your cited reference says: "However, the model depends on neither the view nor the controller." Have you even read the cited article? Doesn't look like it.
    – CodeART
    May 13, 2012 at 18:32
  • 2
    @Crazy Eddie: I don't care what someone on crappy codeproject writes. This is a horrible design. Using an observer to listen for changes is ok, but putting a presentation interface in a domain model is oh so wrong. The cited code from the article is flawed in some fundamental ways in regard to MVC. It even lets the model implicitly depend on the controller. What a crap.
    – Falcon
    May 13, 2012 at 19:11
  • 3
    @Crazy Eddie: lol @ downvote rampage. Did I enrage you?
    – Falcon
    May 13, 2012 at 19:36
-7
  • Controller dispatches model to a view and it processes submitted model from the views, however it is not tightly coupled to a view or a model.

If controller was tightly coupled to a view, then we'll be in a world of web forms. You'd have a code behind which would be tied to a template file (Applicable to ASP.NET web forms)

Because of this, controller is not coupled to a model or a view. It's just a mechanism for processing requests and sending responses.

  • View is tightly coupled to a model. Make changes to your model (e.g. change its property) and you'll have to make changes to your view.

  • Model is not tightly coupled to a view. Make changes to a view, and it'll have no affect on a model.

  • Model doesn't know anything about controller or views where it may be used. Therefore model is not tightly coupled to a view or controller.

Another way to think about this:

  • Make changes to a controller - view and model will be unaffected

  • Make changes to a model - view will break as it relies on a model

  • Make changes to a view - model and controller will be unaffected

This loose coupling in MVC projects is what makes them easy to unit test.

4
  • 1
    This is so wrong it's not funny. Not even worth explaining. Just ignore this answer completely.
    – Reactgular
    May 13, 2012 at 15:53
  • 1
    @MathewFoscarini Stop crying and leave a "correct answer"
    – CodeART
    May 13, 2012 at 16:02
  • 2
    lol, the whole design theory behind MVC is that they are not dependent on each other.
    – Reactgular
    May 13, 2012 at 16:03
  • I've left more information for you, hopefully it'll make sense
    – CodeART
    May 13, 2012 at 16:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.