How do you keep Cocoa controllers too big?

Do you have any tricks or methods to break Cocoa controller classes into smaller pieces? I believe that everything I do, controllers are becoming one of the more complex classes in my design. The basic stuff is simple, but as soon as I have a few passes or action sheets, everything becomes uncomfortably complicated. This is not so bad, but still I would like to reorganize the code into several autonomous parts.

I was thinking of categories, but the code is not so independent (many times he needed to click on viewWillAppear, for example), and I found that I spent a lot of time with the compiler. I also thought about adding functionality in layers using inheritance, but this seems like a hack.

+6
model-view-controller cocoa
source share
3 answers

The problem is not in size, but in responsibility. Does your controller wear more than one hat? If so, paste it into multiple controllers with one job per class.

Categories help with size, but are not responsible. If you are still doing several things in one (merged) class, you still have a problem; moving them to separate files did not solve it.

The presence of several categories in one class leads to the risk of a collision of methods: the implementation of the same method in several categories, possibly by implementing it in category B, forgetting that category A already has one. This will cause a problem when the object sends itself a message, waiting for a response from one category to this message and receiving another.

Declaring all categories in the heading of the main class reduces this risk, as you can see that the other category already has a method by the name you are about to enter. However, each method you add, thereby lengthening the header file, mitigates mitigation.

If your controller has more than one hat, explode it into several classes.

I recommend Martin Fowler's book Refactoring. Refactoring your code clears it, and also explodes classes that are too large (and methods and functions) - this is a subset of such cleaning.

Of course, several classes that were once needed require a replacement for the relationship that was previously internal within the class. Cocoa provides a number of solutions:

You do not need to choose just one, and you do not need to use them all. Which solutions are suitable will depend precisely on the fact that communication requires your new classes with each other.

+4
source share

Categories are the way to go. The trick (for your "wrong independent" stuff) is to declare the category methods in your main .h file (and not in the separate controller + category.h file, they won't), and then implement them in the controller category +. m file. Like this:

//****************** // MyController.h //****************** #import <Cocoa/Cocoa.h> @interface MyContoller : NSObject { NSWindow *window; // stuff to implement in the category NSComboBox *someCombo; NSButton *someButton; } @property IBOutlet NSWindow *window; @property IBOutlet NSComboBox *someCombo; @property IBOutlet NSButton *someButton; @end @interface MyController (MyCategory) - (IBAction)someComboSelected:(id)sender; - (IBAction)someButtonPressed:(id)sender; @end //************************** // MyController+MyCategory.m //************************** #import <Cocoa/Cocoa.h> #import "MyController.h" @implementation MyContoller (MyCategory) - (IBAction)someComboSelected:(id)sender { .... } - (IBAction)someButtonPressed:(id)sender { .... } 

Obviously, I did not include "MyController.m" where you put the "@synthesize" stuff and everything else that is needed for the main controller / awake -from-nib / whatever. In any case, by doing this in this way, your controller methods gain access to category methods and vice versa, and category methods have access to all properties.

+3
source share

In regular Cocoa, the NSViewController can be used to control the complexity of the controller, allowing the "components" in the window to have their own common controllers.

You may be able to do something similar with the UIViewController, or you may need to create “coordination controllers” outside your view / view manager hierarchy to control the behavior of your object models separately.

+2
source share

All Articles