views:

70

answers:

1

I'm a newbie in Cocoa developer, beside this I know well a lot of patterns. So far until now I understand that MVC have in mind avoid dependences between model, view and control. Well, I gave a look in some examples of controller and I found a behavior that apparently do not agree with that goal. Normally, in theses examples, I found a controller creating a instance of model, in other words, the controller is explicitly dependent of the model. For me a solution could be the use of factory pattern to avoid dependence between controller and model.

What you think about it? How you solve that problem?

+2  A: 

In Cocoa, the controller's role is to mediate between the model and the view. There should be a wall between model and view, so you can swap out either one without the other noticing; the controller straddles this wall, and so knows about both.

So, yes, controllers generally do know about both the model and the view. In the Cocoa world, this is normal.

I have never found a good use for “dependency injection” (a.k.a. hiding controller code in model/view code files) or the factory pattern (objects that exist solely to make other objects). Classes should be self-contained; categories to extend them should be rare. And classes, at least in Cocoa, should be capable of making their own instances.

Peter Hosey
In fact MVC make a good job separating model from view, but for me this is not enough.I like to use Dependence injection and Factory patterns, for me they are very helpful.I would like to know if you use TDD. IF yes, how do you do it?
Luiz Siqueira Neto
Simple: Write the tests before the code under test. That has nothing to do with anything in this question, though.
Peter Hosey
For me dependence injection, MVC and TDD have everything to do.Take a look here http://wiki.yak.net/709 .Thank you anyway.
Luiz Siqueira Neto
MVC is important to TDD because controllers pretty much aren't testable (not without mock objects, anyway), whereas views (with Google's testing kit) and model objects are easy to test. Dependency injection has nothing to do with it, as there are other ways to achieve the “loose coupling” necessary for testability. You may want to read http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaFundamentals/ , particularly “Cocoa Design Patterns” and “Communicating With Objects”.
Peter Hosey
Thanks. Right now I'm reading the documentation that you propose, then I'll come back here as soon as possible and tell you if I found an answer to my questions.
Luiz Siqueira Neto
I taken a good look at the documentation and I don't find a direct answer for my question. In "Cocoa Fundamentals Guide" Apple strongly suggest that developers adopt patterns, there I found "Abstract Factory" pattern ( http://bit.ly/9HGI4s ), this one can solve my problem. With "Abstract Factory" I can configure the Model with yours dependences in a way that Control don't know your implementation, only the Protocol implemented by it, this is exactly what I want. This make possible too a easy way to test the Control using Dependence injection to inject Mocks objects instead of real dependences.
Luiz Siqueira Neto
But something bugs me, why I can't find a example about it?PS: Sorry about make you wait, I moved into a new house.
Luiz Siqueira Neto
Look at the subsection of “Abstract Factory”: Cocoa's version of that is the Class Cluster. Class clusters are actually very rare; the plist classes are most of the class clusters. You do not need class clusters or protocols for this purpose; all the controller needs to do is not assume the model objects do anything that isn't explicitly named or documented in their `@interface`s. Conversely, any behavior in the model that other classes should rely on should be documented in the `@interface`, and *should be tested*—you shouldn't mock the model like that. Mocks are best used for controllers.
Peter Hosey
My problem is give a instance of Model to the Control without the Control know the concrete class, I believe that Control don't have the responsibility to create a Model instance but instead just call someone to get it.
Luiz Siqueira Neto
My application have some different Models that have different responsibilities, they don't share the same interface or super class (except of course NSObject), because of this my factory don't act as a cluster, they looks more like a container but in fact it is a factory, this factory have the purpose to give for some client, in this case some Control, a Model instance with all your dependences (aggregations) solved. This give me the possibility to test a Control without use the the real Model but instead giving to it a mocked Model.
Luiz Siqueira Neto
I don't know for sure but I believe that Spring Framework do some in this way.
Luiz Siqueira Neto
If the models are completely different, you should have different controllers controlling them and probably different windows and views displaying them. If the models share some common general nature (e.g., Car) but diverge in more specific matters (Sportscar, Minivan, StationWagon), then you should have one abstract class (Car) with more-specific concrete subclasses, and the Controller should expect only that its model objects are instances of the abstract class, without awareness of the subclasses.
Peter Hosey
I see Models as objects of a Domain Model ( http://bit.ly/12JBqH ), this kind of object can be used by more than one Control and indirectly by more than one View, they can interact with others models. I see a Control inside of a Service Layer ( http://bit.ly/1TgKFj ), Controls will encapsulate the business logic. Probably I will not find a situation like you describe.Maybe we are talking about different things.
Luiz Siqueira Neto
If an application is really complex then Controls can be outside of a Service Layer and just use it. In this case Controls will access operations (methods) of a Service Layer then if I want test a Control I just need inject some Mock instead of the Service Layer.
Luiz Siqueira Neto
Domain Model does sound like a model in Cocoa. Don't say “Control” when you mean controller; a control (NSControl) is a kind of view (NSView). Controllers in Cocoa exist to synchronize between the model and the views that present it to the user, so yes, following Wikipedia's definition, “business logic” should go in the controller(s). Cocoa applications are not architected in a way that matches that Service Layer diagram; while model objects typically do encode/decode themselves in/from some format, controllers decide (or are told by, say, an NSOpenPanel) where to save/load the data to/from.
Peter Hosey
You are right, I'm saying "Control" instead "Controller", sorry. This conversation become very helpful and rich, thanks. I'm trying adapt my knowledge to the Cocoa world, now I realize that I'm in the right path. When I start to use a new IDE or Language I like to adopt it concepts and architecture and avoid to try adapt it to my way of view, this is more productive, that is why I'm making this kind of question. I would like to see a real life example of application using Cocoa, here in Brazil this is almost impossible.
Luiz Siqueira Neto