Reputation: 3696
Today I was getting some refresh about software design patterns.
In particular I was wondering about the difference between MVC and Three-tier-layer. Basically, from what I read on wikipedia and other sources, the main difference between the two is the components interaction:
A fundamental rule in a three tier architecture is the client tier never communicates directly with the data tier;
whilst
...the MVC architecture is triangular: the view sends updates to the controller, the controller updates the model, and the view gets updated directly from the model
Now: if we take the apple docs regarding this matter we see this:
And they clearify that Views and Model shouldn't communicate directly:
view objects are typically decoupled from model objects in an MVC application
and
When a model object changes (for example, new data is received over a network connection), it notifies a controller object, which updates the appropriate view objects
And so on. So, what's the matter here? Is Cocoa adopting its own idea of an MVC, regardless of the common one? Or am I missing something in the common way of seeing an MVC architecture?
Upvotes: 1
Views: 423
Reputation: 490
You are correct the MVC practiced in most cocoa apps is not the MVC as it is defined in the text books. There are many variations of MVC employed by different frameworks. The MVC employed by tools with visual designers are heavily influenced by their visual designer implementation. With XCode you have story boards and nibs. The cocoa libraries and the way concerns are separated are influenced by this. If you want to take advantage of these tools, I would recommend understanding how concerns are separated by Xcode and work within this approach. Your code will coexist with it more smoothly. Apple documentation will help with this.
That being said, MVC is about separation of concerns. Separating concerns is hugely important in designing and maintaining software. Separating concerns properly can reduce dependency, reduce cyclomatic complexity, and make your code much more testable and maintainable. I think it is good that you are paying attention to this and whatever way you structure MVC should look to the reason why you are separating concerns as the guide to implementation.
Upvotes: 0
Reputation: 43330
While it can be said that Cocoa's version of MVC is a sort of subset of the actual definition of MVC, they are not separate entities. The Cocoa version of MVC typically revolves around the use of a View (typically an NSWindow
and/or an NSView
), a controller (typically an NSWindowController
), and a model layer (anything from a simple array to a Core Data stack). The separation of powers in this model is clear, but where in the 'tier' structure that Wiki defines should each of these belong?
I would argue that the Controller and the View are a part of the client layer. Not only is the controller responsible for the delegation between the model and the view, but it is responsible for responding to user events and determining the correct course of action to take during non-framework error handling. By taking this approach to MVC, you can now begin to see how Cocoa does, in fact, satisfy the broader definition of the pattern.
A fundamental rule in a three tier architecture is the client tier never communicates directly with the data tier;
This one's probably the hardest to reason about of the 3, and it involves delving into what "communication" actually means in the context of the pattern. When we say communication, what we mean is that the controller has no direct involvement in the actions taken by the model. That's not to say that the controller cannot order a change in the contents of the model, but rather that the controller does not have a hand in how the model updates itself. The controller acts as a director, not an implementer, which vastly simplifies the creation of a database layer, and is one of the reasons that Core Data and SQLite3 exist as external frameworks rather than as Foundation classes.
view objects are typically decoupled from model objects in an MVC application
That brings up one of the age-old taboos when programming with the pattern: making your views too smart. The controller provides a solid barrier between the model and view, such that the controller acts as a director and a filter for content from the model layer. Without any such barrer, say a tableview, would have to ensure that every cell had a copy of the data from the database, and that each cell knew when and how to update itself when a change is propagated in another cell. In Cocoa, this is where our NSWindowControllers
come in. They manage the display of a root view and act as a barrier between some model and the content of the view it manages. Though, it is important to note that the controller objects in Cocoa are view-biased, mostly because it would be nearly impossible to provide a generic outlet to any kind of model layer without quite a bit of unnecessary glue.
When a model object changes (for example, new data is received over a network connection), it notifies a controller object, which updates the appropriate view objects.
That's the way it should be, for the reasons I've laid out above. But, to build on the networking example you've given, consider this:
Given an NSOperation that fetches data, and a controller that manages a tableview, you would probably not like the controller sticking its fat fingers into the operation, nor would you like the tableview to receive raw NSData
and have to spend valuable rendering time processing the result and displaying it.
And so on. So, what's the matter here? Is Cocoa adopting its own idea of an MVC, regardless of the common one? Or am I missing something in the common way of seeing an MVC architecture?
I guess the conclusion I would draw from this is that your definition of the separation of powers in MVC and in how Cocoa does it is off. Cocoa is fairly rigid about adhering to the pattern, though there is an interesting contemporary movement within the Objective-C community towards MVVM.
Upvotes: 1