+2  A: 

I wouldn't say Cocoa follows the passive view pattern as it's described there. It's saying that the controller does all the work in preparing the view and sending change notifications. In Cocoa a view object will typically respond to KVO notifications (through bindings) from the model, refresh data from the controller that it's bound to, prepare it through data formatters or value transformers, and finally display it on the screen.

Cocoa follows MVC pretty well, although typically the 'controller' aspect is divided into view controllers and model controllers. You can read more about this here. If you have any specific examples on where you're confused, maybe I can provide more detail on the way Cocoa does things.

From the same guide, this section explains some additional design patterns you might find useful. In my own experience though after working through a few projects MVC in Cocoa tends to come pretty naturally, I wouldn't be too concerned about it.

Marc Charbonneau
I appreciate the links, but I wasn't really confused by the patterns; I just wanted to see if Apple was morphing towards a different pattern. The new frameworks/patterns appear (to me) to be going toward the passive view, and I wanted to verify with others if this was true. Thanks though!
+2  A: 

I don't think that Cocoa/OpenStep ever really followed MVC as it's described in, for instance, SmallTalk 80. The SmallTalk Controller is really something which is responsible for interpreting user interaction with the View, which in the case of Cocoa is handled by NSControl and therefore by the View layer (perhaps it's decomposed that way inside the framework, but we're not supposed to peek inside; that's what abstraction is all about :-). In relation to those links of yours, the Controller layer in Cocoa really does fall under the Presenter banner, particularly when considering the various NS*Controller classes from Cocoa Bindings. Those really are a shuttle between a view layer and a model.

In my own applications I tend to have four distinct layers, even in places where they aren't explicitly separated; the view, presenter, service and model. Then the "presenter controllers" and the "service controllers" have entirely separate purposes; the logic and processes are in the services, and the workflow and use cases are in the view controllers. In terms of packaging, if you're into that sort of thing, the services and model together represent an abstract "things to do on stuff" which can be context-independent. The presenters and views represent the "and this is how a user of a Mac OS X application would like to use it" which is dependent upon the lower package, and encapsulates AppKit-specific (and AHIG-specific) classes and behaviour.

Graham Lee
+1  A: 

Uh-oh. MVC = the most misquoted pattern ever. I have read at least 5 different definitions of it.

You may want to read this article by Martin Fowler

+2  A: 

Cocoa is based on MVC (as Apple defines it), and has always been on a trend of doing more and more for you. Here's how it is currently.

  • View layer: NSView, NSWindow, NSCell, their subclasses, and CALayer
  • Controller layer (since 10.3): NSController and subclasses (predominantly NSArrayController)
  • Model layer: Traditionally, you had to do this entirely yourself, but since 10.4, you may be able to use Core Data.

Bindings are powered by KVO (and KVC), and are the glue that bind the three layers together. You bind the views to the controllers and the controllers to the model.

Peter Hosey
+6  A: 

Any code of any complexity has many places where different patterns may apply. MVC is prominent in the Cocoa documents because it explains the relationships between your functional code (the model), your UI code or IB design (the view), and the Cocoa services that tie them together (the controller). That's worth emphasis, particularly in the introductory dox, because you need a little "wake-up call" to stop thinking you have to write it all yourself, and start thinking about how to design your unique parts, and trust the framework to do its plumbing job.

The variant definitions of MVC are legendary, and it's worth pointing out that MVC is not described in the canonical "Gang of Four" book, "Design Patterns." It's also worthwhile to admit that Cocoa's "MVC" model is not the same as the SmallTalk 80 MVC (which is where the terminology originated).

It's probably also worth pointing out that "GoF" actually uses the word "pattern" to denote a particular style of documentation, not the abstract way of designing code that the pattern describes. It's too bad that this usage has largely been lost. If we all understood the word that way, then I could say "it would be really useful if someone would actually write up a pattern for Cocoa's MVC." Then we wouldn't all be so confused!

jackr
A: 

The apple docs actually explain MVC better than anything else I read. Basically the confusion related to MVC is because it is a compound pattern. It consists of many basic patterns. Although MVC was not discussed in Design Pattern by the Gang of four, the basic patterns were.

The main difference I think is that in the Apple world the Controller is a mediator pattern in addition to what it normally is.

So unlike the traditional approach models in Apple's world don't notify views of change. They don't notify anybody in fact. If you want to change a model you have to do it through the controller to make sure everybody is notified of changes.

I think this approach is much better than the traditional one. It puts no constraints on the model objects. They don't have to implement any specific interface. They just have to solve domain specific problems. So you can very easily reuse them in other applications.

It is mainly the controller objects which have to be rewritten in this approach. Of course Apple changed that with bindings. But if you don't use bindings then Controllers is application specific.

Using Apple MVC in C++

I actually followed Apple's design when programming applications in C++ using Qt. Views are QWidget's. I put all code that has to do with appearance in a QWidget subclass. Then I make my controller a QObject subclass and have it create the view objects and connect signals from the QWidgets to slots in my QObject Controller. My model class is a regular class that don't inherit anything from Qt and implement the business logic. It gets modified by the controllers slots.

Alternatively the QWidgets can be created outside of the controller, so you can reuse the controller for other types of views.

Not sure if this helps anybody, but I think it is sometimes easier to think of Cocoa patterns in terms of C++, because we are used to getting pattern explained in terms of a statically typed language like C++ and Java.

Adam Smith