6

Could anyone give an example of why it would be advantageous to use MVC instead of a simpler Model and a View only.

Note: whether it's called MVC or MVP (Model-View-Presenter), I'm talking about the one where the View receives input, then the Controller will respond to the input event by interpreting the input into some action to be done by the Model. When the model changes, the View will update itself by responding to events from the model.

What is disadvantageous of simply letting the Model respond to events in the View and vice versa?

In MVC, if I changed the model in a way that affects the controller then I'll have to do changes in the controller. In Model-View, if I change the Model, I'll have to update the view.

So, it seems like we are introducing complexity by adding the "controller" part?

Saleh Al-Abbas
  • 155
  • 1
  • 10

3 Answers3

4

In MVC, the Model is blind to its environment, the view can be too - passing off (blindly) its events to the controller, which knows more about the view and model. So when all is said and done, the controller is the 'non-reusable' disposable part of the system, since it is the most context aware component.

if I changed the model in a way that affects the controller...

The the model should expose simple CRUD methods in such a way that those using the methods do not have to know anything about the passed update object, nor what really happens inside the model.

This means that the view, IMO, has to do a bit of work by creating the passed record, since Controllers are supposed to be stateless and the view is more persistent. Controllers get triggered and 'kick-in' do their work with a passed object and do not have a state.

The passed data is created by some sort of generic convention.

Let me go even further. Suppose you have a view, a tablegrid, and a control whose enabled property is dependent on item is selected in the grid -- you COULD create a view that handles both those controls and this logic internally, and that would probably be the way to go in such a simplified example.

But the more atomic your views are, the more reusable they become, so you create a view for every, yes every, control. Now you are looking at a situation where views have to know about each other in order to register themselves for the right notification...

This is where the controller steps in, since we want to stick all these dependencies onto him, the long term disposable one. So the controller manages this type of view-to-view notification scheme.

Now your views are ignorant as they can be and independent, thus reusable.

You can code a view without having to know about the system, or the 'business logic' as they like to call it. You can code a model without having to know too much about your goals (though it does help to tweak the model to enable it to return the datasets you have in mind).... but controllers, they are last and you have to have the previous two firmed up before you can wire things together.

Here is another thing to think about -- just as the Model is supposed to abstract-away and provide a generic interface to the underlying implementation of the data it is managing (the client does not know if the data comes from a DB, a file, a program setting, etc) -- the view should also abstract away the control it is using.

So, ultimately this means a view should not (caveat below) have functions/properties that look like this:

public property BackgroundColor{get;set}

Nor

public function ScrollBy(x,y){}

But instead:

public SetProp(string name, object val){}

And

public DoCmd(string name, object val){}

This is a bit contrived, and remember I said ultimately... and you ask why is this a good idea?

With reusability in mind, consider that you may one day want to port things from WinForms to, say, Flex, or simple want to use a new-fangled control library that may not expose the same abilities.

I say 'port' here, but that is really not the goal, we are not concerned with porting THIS particular app, but having the underlying MVC elements generic enough to be carried across to a new flavor -- internally, leaving a consistent and ability-independent external interface intact.

If you didn't do this, then when your new flavor comes along, all your hard references to view properties in the (potentially reusable/refactorable/extendable) controllers have to be mucked with.

This is not to mean that such generic setters and cmds have to be the interface for all your views abilities, but rather they should handle 'edge case' properties as well as the normal props/cmds you can expose in the traditional hard-link way. Think of it as an 'extended properties' handler.

That way, (contrived again), suppose you are building on a framework where your buttons no longer have buttonIcon property. Thats cool because you had the foresight to create a button view interface where buttonIcon is an extended property, and inside the view your conditional code does a no-op now when it receives the set/get.

In summary, I am trying to say that the coding goals of MVC should be to give the Model and View generic interfaces to their underlying components, so when you are coding a Controller you don't have to think to hard about who you are controlling. And while the Controllers are being (seemingly unfairly) set up to be the sacrificial lamb in the long run of re-usability -- this does not mean ALL your controllers are destined for death.

They are hopefully small, since a lot of their 'thinking' has been shoved off into semi-intelligent Models and Views and other controllers (ex: Controller to Sort a Grid or Manipulate a TreeView) -- so being small they can be easily looked at and qualified for reuse in your next project -- or cloned and tweaked to become suitable.

Mark Robbins
  • 2,427
  • 3
  • 24
  • 33
  • I'll give a simple example of why I didn't see the advantage. Assume we are talking about a car. Car View's Accelerate Button clicked, Controller responds by calling Model.Accelerate(), then Model's speed is changed and View responds to Model event and update speed reading on screen. Now, in Model-View (MV) When button clicked, View calls Model.Accelerate() and the same happens without controller involved.In MVC if I changed Accelerate() to IncreaseSpeed() I'll have to update the controller to call this method. In case of MV, I'll do the same update but to the View. – Saleh Al-Abbas Jan 16 '12 at 16:24
  • Continuing previous comment: So, the advantages only applies in the following cases: 1. Your views are not specific to your current project (which is rare). 2. I can't think of any!!! (maybe lack of experience). – Saleh Al-Abbas Jan 16 '12 at 16:31
  • You have a 1-to-1 example there. The view has to know all about the model in EVERY WAY it effects the model. That is a clump of dependencies all in one place. Whereas with the controller, that clump is split - a separate controller for each event - and if something fancier has to occur with the model upon the event, the alteration happens in the controller (ie, the controllers potential for reuse is increase by it being only applicable to one event). With your way, every enhancement/addition decreases the views reusability. – Mark Robbins Jan 17 '12 at 04:19
  • You say views are too specific to the current project. That tells me you are doing something wrong. Perhaps the confusion comes because you are using a frameworks type of MVC (where they make compromises on granularity to have a simpler system). My comments go toward something like PureMVC, or a homebaked solution where YOU are in charge. This means a View (a mediator in PureMVC) is concerned with ONE control, or a set of very simple boring controls (like a submenu). So the view is like a wrapper... it genericizes, but also is where you put your utils for any complex control.. cont. – Mark Robbins Jan 17 '12 at 04:28
  • The only thing a view has to know is the message it is listening for -- and even that can be handled by an external system, when the view is registered. So a view is just an 'MVC control' except a couple things -- it knows how to parse the data that its given (or has settings to show what it wants, or even this parsing can be offloaded to a mediator if its complex), and it knows how to manipulate and hook the events of the underlying control. Its a 'tie-in' that you need to use MVC, and it has its own development path over projects, constantly improving. – Mark Robbins Jan 17 '12 at 04:39
  • 1
    Here is another thing about views -- they do not have to tied to a particular control, but can manage global concerns. For instance you can have a focus mediator (a view, same thing) that tracks and is the go-to-guy for focus concerns (disabling other controls, etc). Or a view that manages a global appearance scheme across all controls. I think of them as functionality layers. – Mark Robbins Jan 17 '12 at 04:54
  • Thanks for your comments/explanations. I'm making a game and trying to use MVC but I'm still in the Model part of the system. Like you said, what I have in mind is a 1-to-1 mapping. For example, I plan to create a Card_X View, Card_X Controller and Card_X Model for each card. Then there is PlayerView, PlayerController, and PlayerModel. So, maybe I didn't get the MVC. If there is any resource, code or book you recommend, that would be great. Thanks again. – Saleh Al-Abbas Jan 17 '12 at 13:17
1

Advantages of MVC/P (I am talking about Supervising Controller here) over MV include:

  • You can handle complex data binding code in the controller, if required.

  • You can test that complex presentation logic without a UI testing framework.

  • You can also have a graphic designer make your views, and not see your code, and not mess up your code when they fix your views.

Neil McGuigan
  • 46,580
  • 12
  • 123
  • 152
1

It actually reduces complexity by separating the workflow logic from the domain logic. It also makes it easier to write unit tests and makes your application easier to maintain and extend.

Imagine if you wanted to add a new data type. With the approach above, you would probably duplicate a lot of the workflow logic in the new class as it would be likely to be tightly coupled to the domain logic.

The discipline involved in separating the workflow logic into the controller makes it more likely that you will have fewer dependencies between workflow and domain logic. Adding a new data type would then be more simple, you create the new domain object and see how much of the controller you can reuse, e.g. by inherited from a controller super class.

It would also make it easier to change frameworks in future - the model would probably not change too much and so would be more portable.

Having said that, you might want to look into MVVM depending on what you are using as your presentation layer: Benefits of MVVM over MVC

Community
  • 1
  • 1
Paul Medcraft
  • 1,386
  • 11
  • 23