tags:

views:

116

answers:

5

Hi,

Im a using the MVC pattern for a while on different frameworks such as (swing, android, gwt ...) Now, I'm learning the iPhone framework and I am quite surprised about MVC implementation. The questions I am asking are about the view and controller interaction.

First of all, that's the way I conceive the MVC pattern :

  • The view and the controller communicate each other through an interface (one for the view and an other one for the controller)

  • In my conception of the MVC pattern, the controller do not have to know the attribute of the view. (for instance, the controller can't have a label attribute instance of the view but can ask the view to change the value of this label via a method of the view interface)

The advantage of not letting the controller directly work on view UI elements is a low coupling and therefore it is possible to test the view easier. The view can be launched and tested on isolation ( or with a mock controller ).

The point is, on iPhone the controllers (ViewController for instance) know directly the UI elements hence my incomprehension. My goal is not to criticise a framework I'm just learning. But if this is really working as I described it, I don't find that really clean...

Is there anybody more experimented with this framework who can give me details / explication ? Or if you feel disagree with my MVC approach, tell me ;)

What's more, I am asking if my approach is not neareast to MVP (described here : http://code.google.com/intl/fr/webtoolkit/articles/testing_methodologies_using_gwt.html) than MVC.

+6  A: 

MVC has meant different things since it was first formalized in Smalltalk, and the NeXTSTEP (Cocoa) version of MVC doesn't exactly match up with Smalltalk's. Smalltalk's break-down is basically like this:

  • The Model holds data
  • The View presents data
  • The Controller manages user interaction

NeXTSTEP's break-down is in practice more like this:

  • The Model holds the data
  • The View draws the data
  • The Controller manages the "logic" (including the "presentation" portion of drawing data)

I'm differentiating here between drawing and presenting in that NSView tends to be dumb about the "meaning" of the data. It just focuses on drawing pixels. So you tend to pass it actual strings rather than an object that the view tears apart and "presents."

It's not a huge difference, but it is the cause of things like what you're running into. The main shift IMO, is that with Cocoa/NeXTSTEP, the view classes have become more and more reusable. In becoming so reusable, more of the application-sensitive portions have needed to move out into the controller. This I believe is generally a benefit because it leads to fewer subclassses, more understandable code and more reusable code... most of the time. In particular, it allows you to more easily swap in views that do fancier drawing (a view that animates a particular way or alternates colors on rows or the like) without bumping into any application-specific logic which generally lives in the controllers.

That said, when a view is particularly complex, I do find it beneficial to create more specialized views that take a data object and manage their own presentation, more in the way I believe you are envisioning.

EDIT: One additional thing to note. Apple's example code often is terrible in terms of design. They almost never include model classes at all, and cram almost everything imaginable into the ViewControllers and worse: the AppController (which should be a very simple object in my opinion). This is generally because their sample code is trying to demonstrate some specific point and they don't want to include the complexity of breaking things up (or the author is being lazy; take your pick). So while I do believe that smart view controllers often work out well, you shouldn't take the example code as a demonstration of this. Unfortunately, there aren't a lot of canonical examples out there of good application-level Cocoa design, since most Cocoa apps are closed source. One good example to learn from is Adium. It is an excellent example of a large, well-designed, multi-developer Cocoa app.

Rob Napier
A: 

Thanks your for responding ;) I understand your position.

But I see problems to this way of working. For instance, if in my view, I replace a "label" by a "textbox", I would have to perform changes in the controller.

Indeed, in my way of working, the view has more code ( the implementation of the view interface i.e. methods such as setMessage... ) but the view is also "dumb" about the meaning of the data. I only send "basics" types such as string, integer, list... and no complex classes.

More generally, I want to separate to the hilt the view and the controller development. I want that once interfaces for views and controllers have been put in place, that the development of the view and the controller are independent !

Maybe, can I use a second controller to perform this task ? So I could have something like this :

View <-> ViewController (which knows view attributes) <-> AnotherController ( which don't knot view attributes) <-> Model

Does it make sense ^^ ?

alexandrebour
(If you make comments as comments, the original poster will be notified.) There is nothing wrong with your approach. I often create model controllers of exactly the type you're describing, along with Manager objects to track all instances of the model object when needed. Picking the right level of abstraction is an important part of good MVC. Over-abstracting the view from the controller for simple views can make it too hard to understand and code. Under-abstracting creates a mess. Experience is needed, but my experience is it's often best to *modestly* under-abstract and plan to refactor.
Rob Napier
Thank you for your experience feedback, now it's clear for me :DYes, what I called AnotherController is exactly, in fine, a ModelController
alexandrebour
If the view is "dumb" about the meaning of the data, this assumes that the presentation of the data to the user will in no way influence how that user perceives the meaning of the data. Non-obvious without a lot of cognitive science type user testing.
hotpaw2
@hotpaw2 I believe you misunderstand. I'm not saying the application is dumb about presentation, only that the intelligence can be held in either the view or the controller, and there are trade-offs in choosing how much of the intelligence to put into each. In the case that the view is dumb about presentation concerns, it is expected that the controller will be equivalently more intelligent. At some point the controller becomes too smart (complex) and more of the smarts should move to the view. This is refactoring and should have no user-visible impact.
Rob Napier
+1  A: 
tc.
A: 

This is just a guess. But my guess is that one reason the the View and the Controller end up more tightly coupled in Mac/iPhone implementations is that if you decouple the interaction control and the presentation too much, the likelyhood that you end up with an uglier and less intuitive feeling interface increases. Whereas more tight coupling encourages the developer into making the the control of the model more closely fit subtile differences in user behavior given their perceptual response to the view presentation. You end up with more UI optimal but less portable code. Value judgements required.

hotpaw2
+1  A: 

The iPhone ViewController is intended to manage a collection of views, all of which combine into a coherent interface. For example, a view controller may manage a scroll view with a dozen label views, a switch view, and two button views. Each UIView-derived piece handles the on-screen drawing of a specific element -- a button, a scroll layer, a label -- with the View Controller directing what data gets put where. So, a UIViewController-derived class focuses on the presentation (more View in the MVC sense), by marshaling data into the right UIView objects (like a Controller.) I think ViewController is an apt term for it.

Sometimes to managed a single screen, a UIViewController will have several other UIViewControllers for specific parts of the display. The UINavigationController, for example, maintains a stack of UIViewControllers each of which handle one page of the display. Cocoa is all about layering.

A UIViewController may and often does have a delegate (and sometimes a data source) that it uses to ask what data belongs in the views and to filter up user input. In my mind, that makes the delegates closer to the MVC Controllers because they are the classes that manage all the models and include any application (business) logic. The AppDelegate is the big one, in charge of managing the overall state of the application. The AppDelegate may keep track of all the data or it may dole out parts of the data to other delegates. I would expect the Facebook app to have one delegate for managing all the Events, another for Wall posts and a third for Photos, each of which report up to the AppDelegate for communicating with Facebook servers.

When I'm writing my apps, I tend to use CoreData for the MVC Model, Delegates for the MVC Controllers and leave the MVC Views to UIViewControllers tasked with wrangling the herds of UIViews.

John Franklin